Today I Learned

Short technical notes, commands, fixes and behaviours learned while building and operating real systems.

Latest notes

Small discoveries worth retaining

Showing all 38 notes.

  1. write memory Makes a Second Source of Truth

    On FRR, a change made in vtysh is gone after a restart unless you save it. Save it on a router whose config file Ansible manages, and the next playbook run quietly puts the old file back.

    AutomationNetworkingAutomationLinux

  2. PyInstaller Cannot See a Streamlit App's Imports

    A Streamlit app is launched by file path, so PyInstaller never analyses it, and every module it imports is missing from the frozen build. Declare them — then derive the list, or test it against the filesystem, so a new module cannot be forgotten.

    AutomationPythonTestingDevelopment

  3. Reasoning Tokens Are Not Counted the Same Way Everywhere

    Through the same Chat Completions endpoint, GPT models counted their hidden reasoning inside completion tokens, and Grok reported it on top. Adding up completion tokens across models adds up different things.

    CloudAILLMAzure

  4. Format-Table in a Loop Captures Formatting, Not Data

    Pipe each iteration of a loop into Format-Table and assign the loop to a variable, and you collect PowerShell's internal formatting instructions instead of your objects. The export afterwards succeeds and contains nothing useful.

    AutomationPowerShellAutomationTroubleshooting

  5. In promtool, 1x5 Means Six Samples

    Prometheus's rule-test series notation a+bxn expands to n+1 values, not n. Off by one, every alert's timing in a test shifts by a scrape interval.

    AutomationObservabilityPrometheusTesting

  6. Google Cloud Renewal by Learning Buys One Year

    Renewing a Google Cloud certification through Google Skills activities extends it by one year. The shorter renewal exam extends it by two, but its window opens far later.

    CloudGoogle CloudCloudCertification

  7. A Stale Socket File Makes a Make Target Lie

    A start target that checks whether a socket path exists will skip starting the daemon after a crash, then report success. Test for a live listener, not for a file.

    AutomationLinuxAutomationTroubleshooting

  8. AppArmor Blocks a vTPM Socket Outside Home

    A lab VM with a virtual TPM works from the home directory and fails from a second data volume. The profile permits socket creation under one path pattern only, and the denial is not in the tool's output.

    Endpoint & BrowserLinuxUbuntuTroubleshooting

  9. The Default localnet ACL Is Wider Than Your Lab

    Uncommenting the stock localnet ACL so a lab network can reach a proxy also admits every other private range, including the wifi the laptop happens to be sitting on.

    NetworkLinuxNetworkingSecurity

  10. Headless RDP Needs an Unlocked Keyring First

    Remote desktop credentials go into the login keyring, and the keyring stays locked until someone logs in at the console. Setting them on a headless machine appears to succeed and produces a connect-then-drop fault.

    Endpoint & BrowserLinuxUbuntusystemd

  11. OpenSSL 3 Writes PKCS#8, FreeRDP Wants PKCS#1

    A self-signed key generated the usual way is rejected with no useful error. The certificate is fine and the key is fine; the private key container format is not.

    IdentityLinuxCertificatesTroubleshooting

  12. OSC 52 Gets You Copy, Not Paste

    The terminal escape sequence that lets a remote editor write to your local clipboard has no reliable read half. Configure copy through it and leave paste to the terminal.

    NetworkLinuxSSHTroubleshooting

  13. SSH Agent Starts at the Console, Not Over SSH

    Agent start-up logic in ~/.profile works when you log in at the machine and silently does nothing when you connect over SSH. Which startup file runs depends on how the shell was invoked.

    AutomationLinuxSSHAutomation

  14. VRF-Sourced Traffic Needs tcp_l3mdev_accept

    A service bound to 0.0.0.0 will not accept connections arriving inside a VRF unless the kernel is told to allow it. The listener looks correct, the route is correct, and the connection is refused.

    NetworkLinuxNetworkingTroubleshooting

  15. Cloudflare Access Checks Must Fail Closed

    For a training-compliance Access evaluator, I treat missing users, invalid requests and database errors as deny conditions instead of accidental allows.

    SecurityCloudflareZero TrustAccess

  16. Bounded Retries for Cloudflare API Calls

    Short-lived Cloudflare API failures can justify a retry, but diagnostic Workers still need a bounded attempt count and a useful fallback value.

    SecurityCloudflareWorkersAPI

  17. Resolve Gateway Rule IDs Before Showing Them

    Cloudflare Gateway can provide a rule ID to a custom block page, but resolving that UUID to the rule name makes support diagnostics much more useful.

    SecurityCloudflareZero TrustGateway

  18. Device Registrations Assign Virtual IPs

    When a Zero Trust diagnostic page needs the virtual IPv4/IPv6 assigned to a device, the active device registration is the useful object to query.

    SecurityCloudflareZero TrustWARP

  19. CSP Nonces in Cloudflare Workers

    For dynamically generated security pages, I use a per-response nonce so required inline script/style can run without falling back to a broad unsafe-inline CSP.

    SecurityCloudflareWorkersSecurity

  20. Gateway Block Pages Need Policy Context

    A CF-Ray header alone does not prove a request came from Gateway, so my Worker requires Gateway-specific query context before rendering diagnostic output.

    SecurityCloudflareGatewayWorkers

  21. Separate Lifecycle for Terraform Backends

    A rebuildable demo environment should not destroy the backend that stores its state, so I manage the S3/DynamoDB backend as a separate Terraform project.

    AutomationTerraformAWSAutomation

  22. Turning Remote Feeds into Terraform Policy Inputs

    An HTTP data source can retrieve an external domain feed, but the useful pattern is to validate and normalize it before Terraform materializes enforcement objects.

    CloudTerraformCloudflareGateway

  23. Derive WARP Routes from Infrastructure

    When Terraform already knows the cloud subnets, those values can become inputs to WARP routing instead of being copied into a second manually maintained list.

    SecurityCloudflareZero TrustWARP

  24. Workers KV Is Backup, Not Source of Truth

    In my Gateway allow-list Worker, Cloudflare lists remain the enforcement state while Workers KV stores backup and synchronization metadata.

    SecurityCloudflareZero TrustWorkers

  25. Why I Tag Container Images With the Commit SHA

    Using the Git commit SHA as a container image tag creates a direct, immutable link between source code, pipeline and deployed artifact.

    AutomationGitGitLabContainers

  26. Deploy Manually Before Automating CI/CD

    When learning a new platform, proving the deployment manually first turns CI/CD into automation of a known-good process.

    AutomationCI/CDDevOpsGitLab

  27. NXDOMAIN Caching Beyond the Windows DNS Cache

    A hostname can continue returning NXDOMAIN after its DNS record exists if another resolver layer has cached the earlier negative response.

    NetworkDNSWindowsNetworking

  28. Windows and WSL CLI Credential Sharing

    A CLI working in PowerShell does not mean the same authentication or configuration will automatically exist inside WSL.

    Endpoint & BrowserWSLWindowsLinux

  29. AD lastLogon vs lastLogonTimestamp

    Why Active Directory exposes multiple logon attributes and why choosing the wrong one can give misleading results.

    IdentityActive DirectoryPowerShellIdentity

  30. Show Astro Drafts Only in Development

    A small Astro content-filtering pattern that makes draft posts visible during local development without publishing them.

    AutomationAstroDevelopmentBlogging

  31. Astro: GitHub to Cloudflare Workers

    The small deployment workflow behind this site: test Astro locally, push to GitHub and let Cloudflare build the production site.

    AutomationAstroCloudflareGitHub

  32. Cloudflare www-to-Apex Redirect

    The simple 301 redirect pattern I use to keep one canonical hostname for a site.

    CloudCloudflareDNSWeb

  33. DNS Names vs IPs for Egress Policy

    Cloud and SaaS services move between addresses. Policy often expresses intent more accurately when it follows the application hostname.

    NetworkCloudflareDNSNetworking

  34. Three Git Commands I Run Before Publishing

    A simple pre-push check for seeing changed, unstaged and staged content before it reaches a public repository.

    AutomationGitGitHubSecurity

  35. PowerShell Process-Scope Execution Policy

    When a local script is blocked by execution policy, Process scope can be useful for a temporary session without changing the machine-wide setting.

    SecurityPowerShellWindowsSecurity

  36. Testing HTTP Redirects with curl.exe

    Use a HEAD request to see the HTTP status and Location header without downloading the complete page.

    NetworkPowerShellHTTPTroubleshooting

  37. WARP Fallback Domains vs Split Tunnels

    DNS resolution and packet routing are related, but a WARP configuration often needs you to reason about them separately.

    NetworkCloudflareWARPDNS

  38. Zero Trust: Find the Failed Control Plane

    Before creating an emergency bypass, work out whether the failure is identity, posture, policy, DNS, tunnel or origin.

    SecurityZero TrustCloudflareTroubleshooting