<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: MournfulCord</title>
    <description>The latest articles on DEV Community by MournfulCord (@mournfulcord).</description>
    <link>https://dev.to/mournfulcord</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3883084%2Fa045ef28-5d0d-4b82-a54d-93fdfc3c858f.jpg</url>
      <title>DEV Community: MournfulCord</title>
      <link>https://dev.to/mournfulcord</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mournfulcord"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>MournfulCord</dc:creator>
      <pubDate>Tue, 14 Jul 2026 14:52:27 +0000</pubDate>
      <link>https://dev.to/mournfulcord/-2gn9</link>
      <guid>https://dev.to/mournfulcord/-2gn9</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/mournfulcord/latency-physics-systems-and-the-future-of-network-design-2ij7" class="crayons-story__hidden-navigation-link"&gt;Latency as a Physical Constraint in Distributed Systems&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/mournfulcord" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3883084%2Fa045ef28-5d0d-4b82-a54d-93fdfc3c858f.jpg" alt="mournfulcord profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/mournfulcord" class="crayons-story__secondary fw-medium m:hidden"&gt;
              MournfulCord
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                MournfulCord
                
              
              &lt;div id="story-author-preview-content-4091652" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/mournfulcord" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3883084%2Fa045ef28-5d0d-4b82-a54d-93fdfc3c858f.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;MournfulCord&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/mournfulcord/latency-physics-systems-and-the-future-of-network-design-2ij7" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 7&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/mournfulcord/latency-physics-systems-and-the-future-of-network-design-2ij7" id="article-link-4091652"&gt;
          Latency as a Physical Constraint in Distributed Systems
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/networking"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;networking&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/distributedsystems"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;distributedsystems&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/systems"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;systems&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/observability"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;observability&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/mournfulcord/latency-physics-systems-and-the-future-of-network-design-2ij7" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;2&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/mournfulcord/latency-physics-systems-and-the-future-of-network-design-2ij7#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              3&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Rust Borrowing Without Fear</title>
      <dc:creator>MournfulCord</dc:creator>
      <pubDate>Fri, 10 Jul 2026 22:12:20 +0000</pubDate>
      <link>https://dev.to/mournfulcord/rust-borrowing-without-fear-578m</link>
      <guid>https://dev.to/mournfulcord/rust-borrowing-without-fear-578m</guid>
      <description>&lt;p&gt;Borrowing is one of the first concepts in Rust that feels different from other languages. If you’re coming from Python, Java, or C, it can seem strict or overly protective. But once you understand what Rust is actually enforcing, you'll see that borrowing is one of the simplest parts of the language.&lt;/p&gt;

&lt;p&gt;At its core, borrowing is just controlled access to data, and Rust gives you two ways to borrow. You have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Immutable borrow (&amp;amp;T): read‑only access&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mutable borrow (&amp;amp;mut T): exclusive write access&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s the entire Borrow model. Everything else is just rules that keep those two forms of access safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Rust Cares So Much
&lt;/h2&gt;

&lt;p&gt;In many languages, you can read and write the same object from anywhere. It’s flexible, but it can also lead to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;unpredictable state changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;accidental mutation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;race conditions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;bugs that only appear during load&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust prevents these by making access patterns explicit. You can have many readers, or one writer, but never at the same time. This rule is simple, but it eliminates entire classes of bugs.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Simple Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Adam"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculate_length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// immutable borrow&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Length: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;update_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// mutable borrow&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Updated: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate_length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;update_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" Smith"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What’s happening here?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**calculate_length** borrows name immutably and is safe to read

**update_name** borrows name mutably, and is safe to modify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Rust ensures these never overlap in unsafe ways. This is borrowing in its most basic form.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Immutable vs. Mutable Rule
&lt;/h2&gt;

&lt;p&gt;Rust allows:&lt;/p&gt;

&lt;p&gt;many immutable borrows, or one mutable borrow, but not both at the same time&lt;/p&gt;

&lt;p&gt;This prevents reading stale data or modifying something while it’s being read. It’s the same rule that makes Rust’s concurrency model so reliable, even in single‑threaded code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Borrowing Makes Your Code Better
&lt;/h2&gt;

&lt;p&gt;Borrowing is a concept that has you think about: who owns the data, who can read it, who can modify it, and when access ends&lt;/p&gt;

&lt;p&gt;Once you start writing with these questions in mind, your code is much more predictable and easier to reason about. This shows you that it's less of a restriction and that it’s a design tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Borrowing is Rust’s method of guaranteeing that your code behaves exactly the way you expect. Still, once you understand immutable vs. mutable access, the borrow checker is less of a barrier and is easier to understand as a safety tool.&lt;/p&gt;

&lt;p&gt;If you’ve found patterns or examples that helped you understand borrowing, I’d love to hear them!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
    <item>
      <title>Latency as a Physical Constraint in Distributed Systems</title>
      <dc:creator>MournfulCord</dc:creator>
      <pubDate>Tue, 07 Jul 2026 21:33:59 +0000</pubDate>
      <link>https://dev.to/mournfulcord/latency-physics-systems-and-the-future-of-network-design-2ij7</link>
      <guid>https://dev.to/mournfulcord/latency-physics-systems-and-the-future-of-network-design-2ij7</guid>
      <description>&lt;p&gt;Latency is often treated as if it can be simply "optimized". But it's much more complex than simply adding a CDN or buying a faster link. After reading (and re-reading) an assortment of books over the last few months, such as &lt;em&gt;The Datacenter as a Computer&lt;/em&gt;, and, &lt;em&gt;High-Performance Browser Networking&lt;/em&gt;, I've come to see latency not as a performance metric, but as a visible expression of physics.&lt;/p&gt;

&lt;p&gt;And if we want to create better networks, or fix the ones that we already have, we need to treat latency as a physical constant and not as a tunable parameter.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Latency Truly Is (Beyond Ping Time)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy5wh924geqejbohctfff.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy5wh924geqejbohctfff.png" alt="A primer on latency and bandwidth - O'Reilly" width="617" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Latency is the sum of several delays, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Propagation Delay (the time it takes for a signal to physically travel through fiber or air. This is bounded by the speed of light.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transmission Delay (the amount of time required to push bits onto the wire.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Queuing Delay (time spent waiting in buffers during congestion.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Processing Delay (time spent in protocol stacks, encryption, and application logic.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These concepts are foundational for understanding modern distributed systems, and latency is a distribution shaped by physics and queuing theory. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why We Cannot Route Around the Speed of Light
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;You cannot route around the speed of light&lt;/strong&gt;. This is the conclusion reached across the systems literature I've studied and by professionals such as Jeff Dean, Luiz Andre Barroso, Martin Kleppmann, and others whose work consistently shows that latency is bound by physics and not just engineering optimism.  &lt;/p&gt;

&lt;p&gt;In &lt;em&gt;The Tail at Scale&lt;/em&gt;, Jeff Dean demonstrates how latency floors dominate distributed systems behavior, especially at the tail; hence, the book's title. Barroso and Hölzle’s The &lt;em&gt;Datacenter as a Computer&lt;/em&gt; makes the physical layout of compute clusters a first‑class design constraint, explicitly tying propagation delay to datacenter geography. Ilya Grigorik’s &lt;em&gt;High Performance Browser Networking&lt;/em&gt; goes even further, showing that even “quick” networks are limited by the speed of light through fiber. All these works together summarize that distance is latency, and latency is correctness.&lt;/p&gt;

&lt;p&gt;You can optimize things like queuing, processing, and protocol overhead, but you cannot shorten the distance between two points without changing the topology. &lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Latency Floor?
&lt;/h2&gt;

&lt;p&gt;If two systems are, say, 3,000 kilometers apart, there is a hard lower bound on latency, even in fiber, where light travels at nearly two-thirds of its vacuum speed. This is known as the latency floor. This means that you can shorten the path and reduce the processing overhead, but geography will remain an obstacle.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Can &lt;em&gt;Really&lt;/em&gt; Do About Latency
&lt;/h2&gt;

&lt;p&gt;You obviously can't change physics. But you can change how systems are designed around it. And after researching the above topics, I've come to believe that the industry has had a more &lt;strong&gt;backwards&lt;/strong&gt; approach to latency: we've focused on optimizing everything except for the part that physics controls. The result of this approach is a system with a normal-looking dashboard and unpredictable reality. &lt;/p&gt;

&lt;p&gt;But the realistic solutions are not tricks or optimizations, but &lt;strong&gt;architectural corrections&lt;/strong&gt;. The methods work because they all align with the physical and mathematical realities that shape latency. Below is an explanation of each possible solution, why it works, and how it changes the future of network design. &lt;/p&gt;

&lt;h2&gt;
  
  
  1: A Topology-Aware System Design
&lt;/h2&gt;

&lt;p&gt;Most of the systems out there are designed as if the network is flat, and every service is reachable from every other service. But since, as I explained before, the distance between nodes determines the latency floor, no amount of optimization can actually push below that. &lt;/p&gt;

&lt;p&gt;Topology-aware design reduces the physical distance that data must travel. This directly lowers propagation delay. What this may look like in practice is co-locating tightly coupled services, regionalizing deployments, and designing microservices around locality boundaries. And if you use areas, or "zones" that reflect physical layout, not just logical grouping, this could eliminate the flat-network assumption that causes many latency and coordination problems. &lt;/p&gt;

&lt;h2&gt;
  
  
  2: A Latency-First Protocol
&lt;/h2&gt;

&lt;p&gt;Protocols such as QUIC and HTTP/3 are considered modern, but they are also designed around the reality that latency is dominated by handshake overhead and retransmission behavior. Latency-first protocols reduce the &lt;em&gt;protocol overhead&lt;/em&gt; portion, the portion caused by round trips and blocking semantics. Key improvements could include: QUIC eliminating TCP's head-of-line blocking, 0-RTT reducing handshake latency, and modern congestion control adapting to jitter and queuing. &lt;/p&gt;

&lt;h2&gt;
  
  
  3: Tail-Latency Engineering
&lt;/h2&gt;

&lt;p&gt;Optimizing for average latency is what most systems do. But average latency is irrelevant to correctness. Systems will perish at the tail (P99, P99.9, and beyond). Tail-Latency engineering reduces the variance in latency, not just the median. This stabilizes distributed systems, consensus protocols, and even automation inference pipelines. &lt;/p&gt;

&lt;h2&gt;
  
  
  4: Optical Bypass Paths
&lt;/h2&gt;

&lt;p&gt;Optical bypass paths reduce latency by minimizing the number of intermediate hops between two points. Rather than routing traffic through several routers and/or switches, a bypass creates a direct optical path, often using something called DWDM (dense wavelength division multiplexing) between distant regions or datacenters. Every hop adds processing or queuing delay and potential jitter. Optical bypass paths, however, eliminate these intermediate steps, reducing both propagation &lt;em&gt;and&lt;/em&gt; processing delay. This creates a sort of "express lanes" between major regions.&lt;/p&gt;

&lt;h2&gt;
  
  
  5: Hardware-Accelerated Transport Paths
&lt;/h2&gt;

&lt;p&gt;A lot of modern networks increasingly rely on SmartNICs, DPUs, and hardware-accelerated transport stacks to reduce processing delays. These devices offload packet processing, encryption, congestion control, and even parts of the transport protocol from the CPU. Processing delay is a significant side of end-to-end latency, especially under load. Hardware acceleration reduces this delay dramatically and also reduces jitter by eliminating CPU scheduling variability. &lt;/p&gt;

&lt;p&gt;(This is a strategy used by many high-performance datacenter networks)&lt;/p&gt;

&lt;h2&gt;
  
  
  6: Latency-Explicit APIs
&lt;/h2&gt;

&lt;p&gt;Most API's treat latency as an implementation detail. But latency-explicit API's expose latency expectations directly to clients. For example, an API might specify that a particular operation has a 20–30 ms latency floor due to geographic constraints, or that a write operation may incur tail latency under certain conditions. By making latency explicit, APIs allow clients to make better decisions about retries, timeouts, caching, and locality.&lt;/p&gt;

&lt;h2&gt;
  
  
  In Conclusion
&lt;/h2&gt;

&lt;p&gt;Latency won't vanish, but the way we design around it &lt;em&gt;can&lt;/em&gt;. The future of networking isn't simply "speedier" networks or clever optimizations; the future is systems that truly acknowledge physics as a design constraint, and behave predictably and efficiently because of it.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and Further Reading
&lt;/h2&gt;

&lt;p&gt;Jeff Dean &amp;amp; Luiz André Barroso, &lt;em&gt;The Tail at Scale&lt;/em&gt;: &lt;a href="https://research.google/pubs/pub40801/" rel="noopener noreferrer"&gt;https://research.google/pubs/pub40801/&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Luiz A. Barroso, Jimmy Clidaras, Urs Hölzle, &lt;em&gt;The Datacenter as a Computer&lt;/em&gt;: &lt;a href="https://cs.yale.edu/homes/yu-minlan/teach/csci599-fall12/papers/dccomputer.pdf" rel="noopener noreferrer"&gt;https://cs.yale.edu/homes/yu-minlan/teach/csci599-fall12/papers/dccomputer.pdf&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Ilya Grigorik, &lt;em&gt;High Performance Browser Networking&lt;/em&gt;: &lt;a href="https://hpbn.co/" rel="noopener noreferrer"&gt;https://hpbn.co/&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Brendan Gregg, &lt;em&gt;Systems Performance&lt;/em&gt;: &lt;a href="https://www.oreilly.com/library/view/systems-performance-2nd/9780136821694/" rel="noopener noreferrer"&gt;https://www.oreilly.com/library/view/systems-performance-2nd/9780136821694/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Martin Kleppmann, *Designing Data‑Intensive Applications *: &lt;a href="https://www.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/" rel="noopener noreferrer"&gt;https://www.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Andrew S. Tanenbaum, &lt;em&gt;Computer Networks&lt;/em&gt;: &lt;a href="https://www.pearson.com/en-us/subject-catalog/p/computer-networks/P200000003507/9780132126958" rel="noopener noreferrer"&gt;https://www.pearson.com/en-us/subject-catalog/p/computer-networks/P200000003507/9780132126958&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;W. Richard Stevens, &lt;em&gt;TCP/IP Illustrated&lt;/em&gt;: &lt;a href="https://www.informit.com/store/tcp-ip-illustrated-volume-1-the-protocols-9780321336316" rel="noopener noreferrer"&gt;https://www.informit.com/store/tcp-ip-illustrated-volume-1-the-protocols-9780321336316&lt;/a&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>distributedsystems</category>
      <category>systems</category>
      <category>observability</category>
    </item>
    <item>
      <title>Back online after a summer cold knocked me out for a bit. Excited to catch up on everyone’s posts and share some progress on my networking tools!</title>
      <dc:creator>MournfulCord</dc:creator>
      <pubDate>Tue, 30 Jun 2026 15:29:16 +0000</pubDate>
      <link>https://dev.to/mournfulcord/back-online-after-a-summer-cold-knocked-me-out-for-a-bit-excited-to-catch-up-on-everyones-posts-1h4m</link>
      <guid>https://dev.to/mournfulcord/back-online-after-a-summer-cold-knocked-me-out-for-a-bit-excited-to-catch-up-on-everyones-posts-1h4m</guid>
      <description></description>
      <category>devjournal</category>
      <category>networking</category>
      <category>sideprojects</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>The Hidden Networking Problem Behind AI Agent Failures</title>
      <dc:creator>MournfulCord</dc:creator>
      <pubDate>Wed, 20 May 2026 16:50:30 +0000</pubDate>
      <link>https://dev.to/mournfulcord/the-hidden-networking-problem-behind-ai-agent-failures-dia</link>
      <guid>https://dev.to/mournfulcord/the-hidden-networking-problem-behind-ai-agent-failures-dia</guid>
      <description>&lt;p&gt;AI agents are being built as if the network is a perfect, low‑latency, lossless abstraction... but it isn’t. And as these systems scale, the real failures won’t come from model quality, but from latency, packet loss, protocol behavior, and the messy reality of distributed systems instead. If we want agents that actually work in production, networking has to become a first‑class design concern again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Part of the AI Conversation That's Missing
&lt;/h2&gt;

&lt;p&gt;As of now, the AI world is tightly focused on bigger models, longer context windows, agent frameworks, orchestration layers, and clever prompting. That's perfectly fine, all interesting. But none of those things matter if the network underneath can't reliably deliver data. &lt;/p&gt;

&lt;p&gt;AI agents all run across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Multi-cloud fabrics&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;edge devices&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;unpredictable wireless links&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;overloaded paths&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;real-world latency&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And even then, most agent architectures are designed as if the network is a solved problem, but it isn't and never was.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Actual Failure Modes Aren't "AI Issues", They're Network Problems
&lt;/h2&gt;

&lt;p&gt;Here are the patterns that continue to show up in modern distributed systems, now amplified by AI workloads:&lt;/p&gt;

&lt;h3&gt;
  
  
  Latency Amplification
&lt;/h3&gt;

&lt;p&gt;Agents that depend on synchronous calls to remote interference endpoints collapse whenever RTT spikes. A small jump, say 40ms to 120 ms, can turn a responsive agent into a stalled one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Retry Storms
&lt;/h3&gt;

&lt;p&gt;Agents retry due to their assumption that the service is slow, not the network. Multiply that across dozens of agents, and you get a self-inflicted outage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Partial observability
&lt;/h3&gt;

&lt;p&gt;Your dashboard can say that everything is green, but your packet capture says otherwise. Retransmits, duplicate ACKs, microbursts, all the concepts that explain behavior, rarely show up in Layer-7-only observability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Protocol mismatch
&lt;/h3&gt;

&lt;p&gt;HTTP/2 and gRPC work fine until you introduce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;MTU fragmentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;middleboxes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;head-of-line blocking&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;asymmetric routing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then your 'fast' protocol becomes bottlenecked.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edge constraints
&lt;/h3&gt;

&lt;p&gt;Everyone wants 'AI at the edge,' but nobody talks about: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;limited bandwidth&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;inconsistent connectivity&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;noisy RF environments&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;small computing budgets&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agents can't reliably count on shipping huge context windows or raw telemetry upstream.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Advice for Anyone Deploying Agents
&lt;/h3&gt;


&lt;div class="crayons-card c-embed"&gt;

  

&lt;p&gt;If you're designing or deploying agents, this is the minimum for reliability: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Measure at the packet level, not the application level alone.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Design for variable latency, instead of just ideal latency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use protocols that can degrade gracefully.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement real backpressure instead of simple retries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cache intelligently, especially when it comes to embedding and model outputs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stream context in prioritized chunks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instrument NIC/PHY telemetry, rather than just HTTP metrics.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test under real network conditions, this includes loss, jitter, and reordering.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your agent's architecture can't handle the network at its worst, it won't survive the &lt;strong&gt;real world&lt;/strong&gt;.&lt;/p&gt;


&lt;/div&gt;


&lt;h2&gt;
  
  
  Observability Has to Go Below Layer 7 Again
&lt;/h2&gt;

&lt;p&gt;Modern observability stacks are great at, logs, traces, and service metrics. But they’re blind to the things that actually break distributed systems, which are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MTU issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;/p&gt;
  What is MTU?
  &lt;p&gt;Maximum Transmission Unit (MTU) is the size of the largest protocol data unit that can be communicated in a single network layer transaction. If your AI's context window data exceeds this without proper fragmentation handling, you see "mysterious" packet loss.&lt;/p&gt;



&lt;p&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;packet loss&lt;/li&gt;
&lt;li&gt;bufferbloat&lt;/li&gt;
&lt;li&gt;link flaps&lt;/li&gt;
&lt;li&gt;retransmit storms&lt;/li&gt;
&lt;li&gt;NIC queue saturation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want agents that behave predictably, you need visibility into the layers where unpredictability thrives.&lt;/p&gt;

&lt;p&gt;This doesn’t mean you have to capture full PCAPs everywhere; even lightweight NIC counters and synthetic probes can reveal the truth just as easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Rust Keeps Showing Up in These Conversations
&lt;/h2&gt;

&lt;p&gt;Rust isn’t just a “fast” language; it has you think like a systems engineer with its core concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ownership&lt;/li&gt;
&lt;li&gt;memory layout&lt;/li&gt;
&lt;li&gt;buffer lifetimes&lt;/li&gt;
&lt;li&gt;concurrency (without data races)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That mindset is essential whenever you’re building telemetry collectors, edge inference runtimes, protocol parsers, or agent‑side networking components.&lt;/p&gt;

&lt;p&gt;Rust gives you the tools to build small, reliable pieces of infrastructure that agents depend on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where This Is All Heading
&lt;/h2&gt;

&lt;p&gt;Here’s what I expect to see over the next few years:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network‑aware agents will outperform everything else out there.&lt;/li&gt;
&lt;li&gt;Observability will shift down the stack, closer to the packet and NIC levels.&lt;/li&gt;
&lt;li&gt;Hybrid inference (local &lt;em&gt;and&lt;/em&gt; remote) will become the default.&lt;/li&gt;
&lt;li&gt;Protocol engineering will matter again, and efficiency will beat sheer force.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The teams that understand networking will create the agents that thrive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;


&lt;div class="crayons-card c-embed"&gt;

  

&lt;p&gt;If you want AI agents that are reliable and useful, make networking your primary design concern. Treat the network as a critical infrastructure. Start now, and audit your agent architecture for network assumptions and proactively engineer for real-world environments.&lt;/p&gt;

&lt;p&gt;The future of AI belongs to those who prioritize improved networking for their product. Actively invest in understanding (and solving) your network challenges. Your agents' success depends on it.&lt;/p&gt;


&lt;/div&gt;


&lt;p&gt;Have you run into an 'AI problem' that turned out to be a networking issue in disguise? I’d love to hear your stories (and how you debugged them) in the comments below.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>networking</category>
      <category>distributedsystems</category>
      <category>rust</category>
    </item>
    <item>
      <title>Rust's Borrow Checker: Translating Intent into Memory Safety</title>
      <dc:creator>MournfulCord</dc:creator>
      <pubDate>Tue, 19 May 2026 13:47:11 +0000</pubDate>
      <link>https://dev.to/mournfulcord/rusts-borrow-checker-translating-intent-into-memory-safety-2k3e</link>
      <guid>https://dev.to/mournfulcord/rusts-borrow-checker-translating-intent-into-memory-safety-2k3e</guid>
      <description>&lt;p&gt;When people start learning Rust, they usually run into the same obstacle: the borrow checker.&lt;/p&gt;

&lt;p&gt;I’ve been there, and everyone has. But the truth is this: The borrow checker isn’t against you; it simply translates what you meant into what the computer needs. Once you understand that, Rust's borrow checker makes a lot more sense.&lt;/p&gt;

&lt;p&gt;Let me show you the moment this made sense for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Classic Problem
&lt;/h2&gt;

&lt;p&gt;Here’s a tiny piece of code that looks harmless:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// this is an error.&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Rust says no. And at first, it's frustrating; it seems like the compiler is being pedantic. But there's a method to this.&lt;/p&gt;
&lt;h2&gt;
  
  
  Rust’s Two Rules
&lt;/h2&gt;

&lt;p&gt;Rust has two simple rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You can have one mutable reference&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OR&lt;/strong&gt; any number of immutable references&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The catch:&lt;/strong&gt; You can never have both at the same time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; Because if something is being changed, Rust doesn’t want other parts of your code reading a half‑changed value. And that's all there is to it.&lt;/p&gt;
&lt;h2&gt;
  
  
  The “Two Doors” Analogy
&lt;/h2&gt;


&lt;div class="crayons-card c-embed"&gt;

  

&lt;p&gt;Imagine your data is a room.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;An immutable reference&lt;/strong&gt; is like giving someone a window into the room.&lt;br&gt;
They can look, but not touch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A mutable reference&lt;/strong&gt; is like giving someone the key to the room.&lt;br&gt;
They can move furniture around.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust’s rule is simple: You can’t have the window open while someone is rearranging the furniture.&lt;/p&gt;


&lt;/div&gt;



&lt;h2&gt;
  
  
  Fixing the Code the Right Way
&lt;/h2&gt;

&lt;p&gt;Here’s our earlier example, but fixed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// do the mutation first&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// then borrow immutably&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, if you really need both at once, you can clone. Cloning is not a crime, especially for beginners:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"original: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"copy: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A Trick That Helps Every Beginner
&lt;/h2&gt;

&lt;p&gt;If you're just starting out, follow this habit: If you’re mutating something, finish all your mutations &lt;em&gt;before&lt;/em&gt; you borrow it. This one habit eliminates most borrow checker errors you'll see.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Rust Does This (And Why It’s a Good Thing)
&lt;/h2&gt;

&lt;p&gt;Languages like Python, Java, and JavaScript let you mutate data while other parts of your code are reading it. Most of the time, it’s totally harmless. But sometimes, it causes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;sneaky race conditions (which usually only occur during production)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;strange bugs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;inconsistent state&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;security issues&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;data corruption&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust prevents all of that, because it's designed to.&lt;/p&gt;

&lt;h2&gt;
  
  
  If You’re Learning Rust, Here’s My Advice
&lt;/h2&gt;

&lt;p&gt;Don’t fight the borrow checker. Instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Borrow when you only need to read&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mutate before you borrow&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone when you need independence&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trust the compiler’s hints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep your functions small&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Return owned data when in doubt&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust rewards those who take the time to understand the mechanics. The borrow checker is just the first step in that shift in perspective.&lt;/p&gt;




&lt;h2&gt;
  
  
  Want More Beginner‑Friendly Rust Posts?
&lt;/h2&gt;

&lt;p&gt;I’m working on a series covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ownership&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;borrowing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;lifetimes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;slices&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;structs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;enums&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pattern matching&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;error handling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;async basics&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want me to cover something specific, or if there's a specific concept that hasn't clicked yet, drop it in the comments! I’ll turn the most requested topic into another post.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Building a Packet Parser in Rust: When PCAP Meets Ownership</title>
      <dc:creator>MournfulCord</dc:creator>
      <pubDate>Wed, 13 May 2026 12:38:55 +0000</pubDate>
      <link>https://dev.to/mournfulcord/building-a-packet-parser-in-rust-when-pcap-meets-ownership-35mh</link>
      <guid>https://dev.to/mournfulcord/building-a-packet-parser-in-rust-when-pcap-meets-ownership-35mh</guid>
      <description>&lt;p&gt;I've been doing packet analysis for a while now. Wireshark is almost always my first port of call when something's wrong on the wire. (Pun intended.) At some point, though, you'll want to go beyond a GUI. You want to write your own tooling, create your own dissection logic, and own the entire pipeline. And that's where Rust comes in.&lt;/p&gt;

&lt;p&gt;This post covers how I approached building a packet parser using both the &lt;code&gt;pcap&lt;/code&gt; and &lt;code&gt;pnet&lt;/code&gt; crates, what each one does, why you need both, and what Rust's ownership model actually means in this context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Rust for Packet Parsing?
&lt;/h2&gt;

&lt;p&gt;The obvious answer is performance. Rust gives you zero-cost abstractions and no garbage collector, which matters when you're parsing high-volume traffic and every microsecond counts.&lt;/p&gt;

&lt;p&gt;But honestly, what hooked me was something different: Rust forces you to be explicit about &lt;strong&gt;memory&lt;/strong&gt;, and packet parsing is a domain where sloppiness gets you immediately. A misread offset, a buffer overrun, an assumption about packet length that ends up being wrong, these aren't just bugs alone; they're also common issues that can silently corrupt your analysis or, in a security tool, become vulnerabilities.&lt;/p&gt;

&lt;p&gt;Rust’s type system and ownership model don’t let you be anything but constructed and organized. That’s maybe frustrating at first, but it quickly becomes an asset once you learn to work with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Two Crates and Why You Need Both
&lt;/h2&gt;

&lt;h3&gt;
  
  
  PCAP: Capturing Packets
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;pcap&lt;/code&gt; crate is your interface to &lt;code&gt;libpcap&lt;/code&gt;. It handles the low-level capture side: opening a device or reading a &lt;code&gt;.pcap&lt;/code&gt; file, applying BPF filters, and handing you raw packet data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pcap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Capture&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Open a live capture on a network interface&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;cap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Capture&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"eth0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.promisc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.snaplen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;65535&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.open&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cap&lt;/span&gt;&lt;span class="nf"&gt;.next_packet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Captured {} bytes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What &lt;code&gt;pcap&lt;/code&gt; gives you is raw bytes. It doesn't give context on what they mean, because that's not its job. You get a timestamp, length, and a &lt;code&gt;&amp;amp;[u8]&lt;/code&gt; slice, then everything else is up to you.&lt;/p&gt;

&lt;h3&gt;
  
  
  PNET: Dissecting Packets
&lt;/h3&gt;

&lt;p&gt;That's where &lt;code&gt;pnet&lt;/code&gt; comes in. The &lt;code&gt;pnet&lt;/code&gt; crate provides structured packet dissection across multiple layers: Ethernet, IPv4/IPv6, TCP, UDP, ICMP, and more. It maps your raw byte slice onto typed structs with named fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pnet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ethernet&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;EthernetPacket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EtherTypes&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pnet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ipv4&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Ipv4Packet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pnet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;tcp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;TcpPacket&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pnet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Packet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;dissect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;EthernetPacket&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Src MAC: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="nf"&gt;.get_source&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dst MAC: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="nf"&gt;.get_destination&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="nf"&gt;.get_ethertype&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nn"&gt;EtherTypes&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Ipv4&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ipv4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Ipv4Packet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="nf"&gt;.payload&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Src IP: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ipv4&lt;/span&gt;&lt;span class="nf"&gt;.get_source&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dst IP: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ipv4&lt;/span&gt;&lt;span class="nf"&gt;.get_destination&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Protocol: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ipv4&lt;/span&gt;&lt;span class="nf"&gt;.get_next_level_protocol&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the "if let Some(...)" pattern throughout. &lt;code&gt;pnet&lt;/code&gt; returns &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; everywhere; if the byte slice is too short or malformed, you get &lt;code&gt;None&lt;/code&gt;. That's basically the API telling you: &lt;em&gt;don't assume the packet is valid just because you received it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the field, I've seen plenty of malformed frames. This pattern handles them correctly by design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting the Two
&lt;/h2&gt;

&lt;p&gt;The typical workflow is: capture with &lt;code&gt;pcap&lt;/code&gt;, dissect with &lt;code&gt;pnet&lt;/code&gt;. Here's a simple integration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pcap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Capture&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pnet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ethernet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;EthernetPacket&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pnet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Packet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;cap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Capture&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"eth0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.promisc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.snaplen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;65535&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.open&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cap&lt;/span&gt;&lt;span class="nf"&gt;.next_packet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;EthernetPacket&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"[+] {} -&amp;gt; {} | EtherType: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="nf"&gt;.get_source&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="nf"&gt;.get_destination&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="nf"&gt;.get_ethertype&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;packet.data&lt;/code&gt; is a &lt;code&gt;&amp;amp;[u8]&lt;/code&gt;. We pass it directly into &lt;code&gt;EthernetPacket::new()&lt;/code&gt;, which borrows it. No copying or allocation required here, only a view into the capture buffer. That's the zero-cost part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Ownership Gets Interesting
&lt;/h2&gt;

&lt;p&gt;Here's something that catches people off guard: &lt;code&gt;pcap&lt;/code&gt;'s &lt;code&gt;next_packet()&lt;/code&gt; returns a packet that borrows from the capture's &lt;strong&gt;internal buffer&lt;/strong&gt;. That means you can't hold onto it past the next loop iteration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This won't compile&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;saved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;pcap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Packet&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cap&lt;/span&gt;&lt;span class="nf"&gt;.next_packet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;saved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Error: lifetime issue&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rust is telling you something here: the underlying buffer gets reused. If you want to store packet data, you need to own a copy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cap&lt;/span&gt;&lt;span class="nf"&gt;.next_packet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;owned&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Now you own it&lt;/span&gt;
    &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;owned&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a Rust quirk, but it's also a faithful model of how &lt;code&gt;libpcap&lt;/code&gt; actually manages its capture buffer. The borrow checker is surfacing behavior that C code would let you get wrong and not bring to your attention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading from a &lt;code&gt;.pcap&lt;/code&gt; File
&lt;/h2&gt;

&lt;p&gt;Live capture isn't always what you want. For offline analysis or replay, you can open a saved capture file instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;cap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Capture&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"capture.pcap"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cap&lt;/span&gt;&lt;span class="nf"&gt;.next_packet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Same dissection logic as live capture&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API is identical. All you have to do is swap the source, keep the rest. This is useful for testing your parser on known traffic without needing a live interface, something I do regularly when developing new dissection logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going Deeper: TCP Layer
&lt;/h2&gt;

&lt;p&gt;Once you're past Ethernet and IPv4, getting to TCP is another layer of the same pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pnet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;IpNextHeaderProtocols&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pnet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ipv4&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Ipv4Packet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pnet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;tcp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;TcpPacket&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pnet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Packet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;parse_tcp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ipv4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Ipv4Packet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ipv4&lt;/span&gt;&lt;span class="nf"&gt;.get_next_level_protocol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nn"&gt;IpNextHeaderProtocols&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Tcp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;TcpPacket&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ipv4&lt;/span&gt;&lt;span class="nf"&gt;.payload&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"TCP {}:{} -&amp;gt; {}:{}  flags: {:08b}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;ipv4&lt;/span&gt;&lt;span class="nf"&gt;.get_source&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="nf"&gt;.get_source&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;ipv4&lt;/span&gt;&lt;span class="nf"&gt;.get_destination&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="nf"&gt;.get_destination&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="nf"&gt;.get_flags&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The flags field is a bitmask. You can check individual flags like SYN, ACK, FIN against &lt;code&gt;pnet::packet::tcp::TcpFlags&lt;/code&gt; constants, which is where things start getting useful for detecting specific traffic patterns or anomalies.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Is Good For
&lt;/h2&gt;

&lt;p&gt;This combination gives you a nice foundation for concepts like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Custom traffic analysis&lt;/strong&gt;: filter and inspect exactly what you care about, without Wireshark's GUI in your way&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Telemetry pipelines&lt;/strong&gt;: feed parsed fields into your own metrics or alerting system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protocol-level diagnostics&lt;/strong&gt;: spot things like SYN floods, retransmissions, or unusual flag combinations programmatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Field tooling&lt;/strong&gt;: a single compiled binary you can drop onto any Linux box and run instantly&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;This is the foundation. From here, you can layer in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UDP and ICMP dissection (same pattern, different protocol structs)&lt;/li&gt;
&lt;li&gt;BPF filters on capture to reduce noise (&lt;code&gt;cap.filter("tcp port 443", true)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Writing parsed output to a structured format for further analysis&lt;/li&gt;
&lt;li&gt;Async capture with &lt;code&gt;tokio&lt;/code&gt; for high-throughput environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm building all of this into a simple Rust PCAP tool I've made, and I'll be sharing more of that work in future posts and tutorials.&lt;/p&gt;

&lt;p&gt;If you're already working with &lt;code&gt;pcap&lt;/code&gt; or &lt;code&gt;pnet&lt;/code&gt;, I'd love to hear what you're building! And if you've hit a wall with the borrow checker in this context, ask away. Rust's ownership model looks entirely different once you see it in the context of packet data.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>networking</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
    <item>
      <title>Porting a Config Validator to Java for Minimal Environments</title>
      <dc:creator>MournfulCord</dc:creator>
      <pubDate>Sun, 03 May 2026 03:20:35 +0000</pubDate>
      <link>https://dev.to/mournfulcord/porting-a-config-validator-to-java-for-minimal-environments-o7o</link>
      <guid>https://dev.to/mournfulcord/porting-a-config-validator-to-java-for-minimal-environments-o7o</guid>
      <description>&lt;p&gt;My previous Python config validator was great for local development, but it hit a wall in minimal "distroless" containers and hardened environments where Python isn't much of an option.&lt;/p&gt;


&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/mournfulcord/how-a-simple-python-validator-prevents-real-world-config-outages-cfh" class="crayons-story__hidden-navigation-link"&gt;How a Simple Python Validator Prevents Config Outages&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/mournfulcord" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3883084%2Fa045ef28-5d0d-4b82-a54d-93fdfc3c858f.jpg" alt="mournfulcord profile" class="crayons-avatar__image" width="552" height="552"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/mournfulcord" class="crayons-story__secondary fw-medium m:hidden"&gt;
              MournfulCord
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                MournfulCord
                
              
              &lt;div id="story-author-preview-content-3562664" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/mournfulcord" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3883084%2Fa045ef28-5d0d-4b82-a54d-93fdfc3c858f.jpg" class="crayons-avatar__image" alt="" width="552" height="552"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;MournfulCord&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/mournfulcord/how-a-simple-python-validator-prevents-real-world-config-outages-cfh" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 28&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/mournfulcord/how-a-simple-python-validator-prevents-real-world-config-outages-cfh" id="article-link-3562664"&gt;
          How a Simple Python Validator Prevents Config Outages
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/sre"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;sre&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/mournfulcord/how-a-simple-python-validator-prevents-real-world-config-outages-cfh#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              2&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


&lt;p&gt;Sometimes you can't control the environment; you can only control the tool. To ensure our validation logic could run anywhere from a CI runner to a bare-bones production box, I rewrote the tool in Java. This version focuses on portability, zero external dependencies, and "fail-fast" logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a Java version?
&lt;/h2&gt;

&lt;p&gt;A few reasons kept coming up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zero external dependencies:&lt;/strong&gt; no pip, no venv, no system packages&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easy to bundle:&lt;/strong&gt; one JAR or native image&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Runs anywhere:&lt;/strong&gt; CI, containers, internal tooling&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Teams already familiar with JVM tooling
&lt;/h2&gt;

&lt;p&gt;The logic is the same as the Python version:&lt;br&gt;
load config, check structure, fail fast.&lt;/p&gt;

&lt;p&gt;The difference is the runtime assumptions.&lt;/p&gt;
&lt;h2&gt;
  
  
  The CLI structure
&lt;/h2&gt;

&lt;p&gt;The tool is intentionally small:&lt;/p&gt;

&lt;p&gt;ConfigLoader: loads YAML/JSON.&lt;/p&gt;

&lt;p&gt;Validator: checks required keys and types&lt;/p&gt;

&lt;p&gt;HostValidator: regex validation for hostnames&lt;/p&gt;

&lt;p&gt;DatabaseValidator: nested key checks&lt;/p&gt;

&lt;p&gt;Main: CLI entrypoint&lt;/p&gt;

&lt;p&gt;Nothing fancy. No frameworks, just enough structure to keep it readable.&lt;/p&gt;
&lt;h2&gt;
  
  
  Loading YAML or JSON in Java
&lt;/h2&gt;

&lt;p&gt;I kept the loader simple. I'm using Jackson (jackson-databind and jackson-dataformat-yaml) to handle the parsing logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ObjectMapper&lt;/span&gt; &lt;span class="n"&gt;yamlMapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;YAMLFactory&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;ObjectMapper&lt;/span&gt; &lt;span class="n"&gt;jsonMapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;loadConfig&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Path&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="nc"&gt;Files&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exists&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Config file not found: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Files&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;endsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".yaml"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;endsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".yml"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;yamlMapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;endsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".json"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jsonMapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unsupported file type: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Same behavior as the Python version, just typed differently.&lt;/p&gt;
&lt;h2&gt;
  
  
  Required keys and type checking
&lt;/h2&gt;

&lt;p&gt;Java doesn’t have Python’s dynamic feel, so I defined expected types like this instead:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;REQUIRED_KEYS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"service_name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"port"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"debug"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"allowed_hosts"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And the validator walks through them:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;REQUIRED_KEYS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entrySet&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getKey&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;containsKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Missing required key: '"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"'"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid type for '"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"': expected "&lt;/span&gt;
                &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSimpleName&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", got "&lt;/span&gt;
                &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getSimpleName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Hostname validation
&lt;/h2&gt;

&lt;p&gt;Same regex, same idea:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pattern&lt;/span&gt; &lt;span class="no"&gt;HOST_REGEX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Pattern&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"^[a-zA-Z0-9.-]+$"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;validateHosts&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;hosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"allowed_hosts"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!(&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="no"&gt;HOST_REGEX&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matcher&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid host value: '"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"'"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Nested database validation
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;validateDatabase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;dbObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"database"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dbObj&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!(&lt;/span&gt;&lt;span class="n"&gt;dbObj&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?,&lt;/span&gt; &lt;span class="o"&gt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid type for 'database': expected Map"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;containsKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"host"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Missing 'database.host'"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;containsKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"port"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Missing 'database.port'"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"port"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid type for 'database.port'"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Same checks, different language.&lt;/p&gt;
&lt;h2&gt;
  
  
  Running it
&lt;/h2&gt;

&lt;p&gt;The CLI is uncomplicated:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-jar&lt;/span&gt; validator.jar config.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If something’s wrong, it prints errors and exits with a non‑zero code.&lt;br&gt;
If everything’s fine, it keeps quiet.&lt;/p&gt;

&lt;p&gt;That’s all there is to it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
A validator doesn’t need to be complex to be useful.&lt;br&gt;
It simply needs to run reliably in the environments you care about.

&lt;p&gt;Python works great until you’re on a host that doesn’t have Python.&lt;br&gt;
Java works great until you’re on a host that doesn’t have Java available.&lt;br&gt;
But the language isn’t the point; The point is catching failures before they turn into outages. This Java CLI is just another way to do that.&lt;br&gt;

&lt;/p&gt;
&lt;/div&gt;



&lt;p&gt;What’s your 'go-to' language when you need a tool to run absolutely anywhere? Do you stick with the JVM, or have you moved toward Go/Rust for these types of CLI tools? I'd love to hear about the constraints you're working with.&lt;/p&gt;

</description>
      <category>java</category>
      <category>devops</category>
      <category>devshow</category>
      <category>cli</category>
    </item>
    <item>
      <title>What I Learned About Networking as a 14-Year-Old Intern</title>
      <dc:creator>MournfulCord</dc:creator>
      <pubDate>Tue, 28 Apr 2026 20:25:45 +0000</pubDate>
      <link>https://dev.to/mournfulcord/what-i-learned-about-networking-as-a-14-year-old-intern-1090</link>
      <guid>https://dev.to/mournfulcord/what-i-learned-about-networking-as-a-14-year-old-intern-1090</guid>
      <description>&lt;p&gt;When I was fourteen, I got my first real taste of networking, not from a classroom or from a cert, but from an internship my uncle offered me at a local tech business (not the same one I work at now). I wasn’t paid or experienced. I was just a kid who loved puzzles and patterns.&lt;/p&gt;

&lt;p&gt;But what I saw changed the way I thought about this field forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quality over shortcuts
&lt;/h2&gt;

&lt;p&gt;I watched techs who were getting paid to care… not care. I saw people take shortcuts, tape things together, shrug at problems, and treat the schools and clinics they served like just another ticket in the queue. Meanwhile, the people who depended on them: teachers, front‑desk staff, and principals, were stressed, confused, and occasionally left waiting.&lt;/p&gt;

&lt;p&gt;I couldn’t stand that.&lt;/p&gt;

&lt;p&gt;So, I did the opposite. I took every issue seriously. I asked questions. I made phone calls when others didn’t bother. I traced cables properly instead of taping them to the wall. I treated every outage like it mattered, because to the people on the other end, it did.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Moment It All Clicked
&lt;/h2&gt;

&lt;p&gt;The moment that sealed it for me was when a switch went down at a school. My uncle was stressed. The staff was stressed. Kids were stuck in limbo. While everyone else ate lunch, I helped reconfigure the switch and brought the network back online. The teacher’s relief, that look of “thank you, I can breathe again”, hit me harder than any technical achievement ever had.&lt;/p&gt;

&lt;p&gt;That’s when I realized networking isn’t just about packets and protocols. It’s about people. It’s about restoring calm amid chaos. It’s about being the person others can rely on.&lt;/p&gt;

&lt;p&gt;Today, I’m still in love with the field, the complexity, the constant learning, the deep corners of the stack. But more than anything, I’m in love with the responsibility. People deserve techs who care. People deserve quality. People deserve someone who shows up with pride in their work.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Advice...
&lt;/h2&gt;


&lt;div class="crayons-card c-embed"&gt;

  

&lt;p&gt;If you’re a young tech reading this: your age doesn’t define your impact. Your title doesn’t define your value. What defines you is how much you care, how much you’re willing to learn, and how seriously you take the people who depend on you.&lt;/p&gt;

&lt;p&gt;Be the tech who gives a damn. It matters more than you think.&lt;/p&gt;


&lt;/div&gt;


&lt;p&gt;What was the '&lt;em&gt;aha&lt;/em&gt;' moment in your career when you realized your work was about more than just the technical specs? I'd love to hear your stories in the comments!&lt;/p&gt;

</description>
      <category>community</category>
      <category>networking</category>
      <category>beginners</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>How a Simple Python Validator Prevents Config Outages</title>
      <dc:creator>MournfulCord</dc:creator>
      <pubDate>Tue, 28 Apr 2026 12:10:00 +0000</pubDate>
      <link>https://dev.to/mournfulcord/how-a-simple-python-validator-prevents-real-world-config-outages-cfh</link>
      <guid>https://dev.to/mournfulcord/how-a-simple-python-validator-prevents-real-world-config-outages-cfh</guid>
      <description>&lt;p&gt;Not all outages I’ve seen were caused by exotic bugs or failing hardware. A majority were caused by simple mistakes: broken configs, malformed YAML, wrong types, or a missing field that nobody noticed before pushing.&lt;/p&gt;

&lt;p&gt;I built this tool after hearing how a config push took down a service because someone missed a single field. It wasn’t a devastating failure, just a small oversight that slipped through, but it still cost hours to unwind. That stuck with me. A lightweight validator could prevent the kind of mistakes that quietly pile up and turn into outages. You don't always get that second chance, so catching mistakes early matters.&lt;/p&gt;

&lt;p&gt;And the thing is, you don’t always need a full schema system to avoid that, either. Sometimes a small, focused validator is enough to catch obvious problems before they become real ones.&lt;/p&gt;

&lt;p&gt;This post walks through a Python tool that: loads YAML or JSON configs, checks for required keys and types, and prints clear, actionable errors.&lt;/p&gt;

&lt;p&gt;If you work with configs at all, this is one more tool you can keep in your belt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a config validator matters
&lt;/h2&gt;

&lt;p&gt;Configs break more often than hardware. A single wrong indent, a missing key, or a string where an integer should be is all that it takes.&lt;/p&gt;

&lt;p&gt;A lightweight validator gives you: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fast feedback:&lt;/strong&gt; Catch errors before they hit CI. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent checks:&lt;/strong&gt; Ensure every config follows the same rules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fewer surprises:&lt;/strong&gt; Reduce the chance of deployment-day outages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s not meant to replace full schema validation, but to prevent the obvious stuff from becoming outages. The idea behind the tool is simple: load the config, check the structure, and fail fast if something looks wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loading YAML or JSON in Python
&lt;/h2&gt;

&lt;p&gt;Here’s the loader function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;  &lt;span class="c1"&gt;# pip install pyyaml
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;FileNotFoundError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Config file not found: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.yaml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.yml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safe_load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unsupported file type: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (use YAML or JSON)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Defining required keys and expected types
&lt;/h2&gt;

&lt;p&gt;This is the simplest form of validation: “Does this key exist, and is it the right type?”&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;REQUIRED_KEYS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;service_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;port&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;debug&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;allowed_hosts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Validating the config
&lt;/h2&gt;

&lt;p&gt;This checks for missing keys and wrong types:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected_type&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;REQUIRED_KEYS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Missing required key: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;

        &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected_type&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid type for &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;: expected &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;expected_type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;got &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Example: good vs. bad config
&lt;/h2&gt;

&lt;p&gt;Good YAML:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;service_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;
&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;allowed_hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api.example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Bad YAML:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;service_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;   &lt;span class="c1"&gt;# wrong type
&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;false&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# wrong type
# allowed_hosts missing entirely
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Invalid&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;port&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;span class="n"&gt;Invalid&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;debug&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;span class="n"&gt;Missing&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;allowed_hosts&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Hostname regex validation
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;

&lt;span class="n"&gt;HOST_REGEX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^[a-zA-Z0-9.-]+$&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_hosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;hosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;allowed_hosts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="n"&gt;invalid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;hosts&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;HOST_REGEX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;invalid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid host value: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Nested key validation (for example: database config)
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;database&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid type for &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;database&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;: expected dict&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Missing &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;database.host&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;port&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Missing &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;database.port&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;port&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid type for &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;database.port&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;: expected int, got &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;port&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Run it with:&lt;/p&gt;

&lt;p&gt;python validator.py config.yaml&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  
&lt;h3&gt;
  
  
  Why this helps in real environments
&lt;/h3&gt;

&lt;p&gt;In the field, the smallest mistakes cause the biggest (and unnecessary) headaches. A missing key, a wrong type, a bad indent, none of it looks serious until it takes down something that people rely on. &lt;/p&gt;

&lt;p&gt;Tools like this don’t replace experience, but they make your experience count. They catch the boring failures before they turn into outages that take up your entire day.&lt;/p&gt;


&lt;/div&gt;



&lt;h2&gt;
  
  
  What’s next
&lt;/h2&gt;

&lt;p&gt;In a follow‑up post, I’ll show how I turned the same idea into a small Java CLI for environments where Python isn’t available or where teams prefer a single binary.&lt;/p&gt;

&lt;p&gt;If you’ve got ideas for other checks you’d want to see in a validator, I’d love to hear them. The best tools come from real problems.&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>devops</category>
      <category>sre</category>
    </item>
    <item>
      <title>What Being a Field Tech Taught Me About Real-World Networking</title>
      <dc:creator>MournfulCord</dc:creator>
      <pubDate>Fri, 24 Apr 2026 00:21:33 +0000</pubDate>
      <link>https://dev.to/mournfulcord/what-being-a-field-tech-taught-me-about-real-world-networking-15ga</link>
      <guid>https://dev.to/mournfulcord/what-being-a-field-tech-taught-me-about-real-world-networking-15ga</guid>
      <description>&lt;p&gt;I started seriously working in IT at 15, but it wasn’t until I turned 16 that I really came to understand what “networking” meant beyond diagrams and certification books. Working for a local tech business that handles everything from managed IT services and cybersecurity to structured cabling and network infrastructure, I got thrown into situations where the network isn’t theoretical; it’s the backbone of a school, a clinic, a government office, or a small business trying to stay afloat.&lt;/p&gt;

&lt;p&gt;Nothing accelerates learning like walking into a site where the WiFi is down, switches are unlabeled, and the only documentation is a sticky note that reads, "DO NOT TOUCH."&lt;/p&gt;

&lt;p&gt;At 17, I went from learning to truly studying. I wanted to know why things worked as they did. Why does a link flap? Why does a device negotiate at 100 Mbps instead of a gigabit? Why does a packet capture reveal patterns unlike user-reported symptoms? That curiosity pushed me deeper into overlooked network layers.&lt;/p&gt;

&lt;p&gt;I learned to read the physical layer like a language: signal integrity, duplex mismatches, impedance issues, and the subtle clues NICs give long before a device "officially fails." I began troubleshooting at Layer 2 with intention, not guesswork: spanning-tree behavior, ARP anomalies, VLAN misconfigurations, broadcast storms, and the fun surprises you find when someone connects a switch to itself because "it fit."&lt;/p&gt;

&lt;p&gt;Packet analysis became one of my favorite tools, not because it’s glamorous, but because it’s honest. I reach for Wireshark almost every time, since it’s simple and lets me see all the traffic down to each frame and protocol exchange. Logs can lie. Users can misremember. But packets don’t. They tell you precisely what happened, down to the microsecond, if you know how to listen.&lt;/p&gt;

&lt;p&gt;And cabling, the part of networking everyone claims is “simple”, became something I genuinely enjoy. There’s an art to building infrastructure that’s clean, reliable, and future‑proof. Good cabling makes networks predictable. Bad cabling makes networks unstable and alive in all the wrong ways.&lt;/p&gt;

&lt;p&gt;Over the past few years, I’ve helped design, repair, and optimize networks across schools, healthcare clinics, government offices, small businesses, and residential environments. I’ve learned how to build infrastructure from the ground up and keep systems running for people who depend on them.&lt;/p&gt;

&lt;p&gt;But the part that keeps me in this field is the service aspect. Networking isn’t abstract when you’re the one restoring connectivity for a clinic that needs access to patient records or fixing a school’s Wi-Fi so students can actually learn. It’s hands‑on, unpredictable, and it matters because it's meaningful.&lt;/p&gt;

&lt;p&gt;I’m still learning, constantly, just like all techs, and that’s the best part. Networking is deep, layered, and endlessly evolving. Whenever I believe I’ve mastered something, I find another corner of the stack worth exploring.&lt;/p&gt;

&lt;p&gt;In future posts, I’ll be sharing more about the technical side of what I’ve learned: packet analysis workflows, telemetry insights, L1/L2 troubleshooting strategies, and the occasional field story that every technician can relate to. If you’re into the practical side of networking, you’ll probably feel right at home.&lt;/p&gt;

</description>
      <category>networking</category>
      <category>learning</category>
      <category>community</category>
      <category>network</category>
    </item>
  </channel>
</rss>
