<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="https://theexceptioncatcher.com/feed" rel="self" type="application/atom+xml" /><link href="https://theexceptioncatcher.com/" rel="alternate" type="text/html" hreflang="en-US" /><updated>2026-05-01T04:33:57+00:00</updated><id>https://theexceptioncatcher.com/feed</id><title type="html">TheExceptionCatcher</title><author><name>Steven Hicks</name></author><entry><title type="html">What Comes Next</title><link href="https://theexceptioncatcher.com/2026/04/new-adventures/" rel="alternate" type="text/html" title="What Comes Next" /><published>2026-04-14T00:00:00+00:00</published><updated>2026-04-14T00:00:00+00:00</updated><id>https://theexceptioncatcher.com/2026/04/new-adventures</id><content type="html" xml:base="https://theexceptioncatcher.com/2026/04/new-adventures/"><![CDATA[<p>Recent massive shifts at Oracle gave me something I didn’t expect. A pause.</p>

<p>It’s giving me more opportunities to drink tea, sit with things, think, and hopefully the pickelball court when the weather is nicer and I’m recovered from an ankle injury.</p>

<p>In my last role, I spent a lot of time exploring AI assisted development, especially spec driven workflows,  and had the opportunity to give a talk on “Context Engineering.”</p>

<p>I haven’t had a lot of time to spend on blogging. But I’ve been busy. Hopefully in this time, I can get back to writing.</p>

<h2 id="whats-coming-next">What’s Coming Next:</h2>

<p>I’m planning a series of posts ranging from a reflection of personal projects to the deep/technical/educational:</p>

<ul>
  <li><strong>Vibe-coding Chronicles</strong>: I build an E-Ink Transit/Train Tracker. I also had a vibe coded Movie Night Planner completely fall apart.</li>
  <li><strong>A Full Guide on LLMs</strong>: I found it surprisingly hard to get started and learn about LLMs. A lot of the resources made massive assumptions, they overstated the capiblities, or they failed to explain why the technology solves a problem I may have. I’m hoping to write a series that will take the reader from getting a sense of what LLMs are and move all the way to Agent Orchestration. (Other topics include: Model definitions, comparisons of models, Heretic/Uncensored Models, AI Coding tools, and should move to building agents)</li>
  <li><strong>Self-Hosting and Local AI</strong>: I plan on sharing how I got an Ollama hosted service up and running. I also plan on sharing how I moved from Ollama to llama.cpp.</li>
  <li><strong>My Experience with GraphineOS</strong>: What is it like from day to day, and what is it like depending on OSS software.</li>
  <li>Contributor License Agreements and How They’re Hostile to the OSS World</li>
  <li><strong>Book Review</strong>:“Vibe Coding: Building Production-Grade Software With GenAI, Chat, Agents, and Beyond” I’m nearly done with this book, but it felt like a better started than many of the other AI books I’ve tried to get into.</li>
</ul>

<h2 id="yuck-more-ai--seriously">Yuck, more AI? … Seriously?!</h2>

<p>I know how you feel. There’s too much noise, too much marketing and way too much fearmongering. I have no interest in hyping up this tool. What I remain interested in is communicating about what works well and acknowledging where it fails.</p>

<h2 id="how-can-i-use-your-help">How Can I Use your Help?</h2>

<p>I’m currently exploring what comes next professionally. I’m focused on Staff+ backend roles (Chicago or Remote), particularly around:</p>

<ul>
  <li>JVM/Scala/Functional Programming</li>
  <li>Distributed Systems and Data engineering</li>
  <li>AI- Assisted Systems and Agents</li>
  <li>Go and/Rust. (I’m excited to learn Rust).</li>
</ul>

<p>If you’re working in those spaces, or think I could help your team build something meaningful. I’d love to connect at <a href="https://www.linkedin.com/in/stevenkhicks/">Linkedin</a></p>]]></content><author><name>shicks</name></author><category term="career" /><category term="rif" /><category term="reflection" /><category term="software-engineering" /><category term="staff-engineering" /><category term="scala" /><category term="functional-programming" /><category term="golang" /><category term="rust" /><category term="ai" /><category term="llms" /><category term="ai-agents" /><category term="self-hosting" /><category term="ollama" /><category term="llama-cpp" /><category term="grapheneos" /><category term="open-source" /><category term="distributed-systems" /><category term="technical-blog" /><category term="whats-next" /><summary type="html"><![CDATA[Recent massive shifts at Oracle gave me something I didn’t expect. A pause.]]></summary></entry><entry><title type="html">GitHub Actions: The Hidden Billing Trap</title><link href="https://theexceptioncatcher.com/2026/02/github-billing/" rel="alternate" type="text/html" title="GitHub Actions: The Hidden Billing Trap" /><published>2026-02-02T00:00:00+00:00</published><updated>2026-02-02T00:00:00+00:00</updated><id>https://theexceptioncatcher.com/2026/02/github-billing</id><content type="html" xml:base="https://theexceptioncatcher.com/2026/02/github-billing/"><![CDATA[<p>You might be unknowingly paying for GitHub Actions even after your workflows have finished. Let’s set the stage for
being me:  you’ve forked a project, enabled the GitHub actions, stayed under your limit, and contributed a great change
to an open source project. You’re all good right? Karma’s good, it’s great code, and you stayed at a low limit usage
under the GitHub actions allowances.</p>

<p>Fast-forward a month, and you’ll notice that your account is still being billed. What’s up? You’re not running actions
anymore yet there still claims to be billing. It was about $4 a month, for nothing running. It’s not a lot, but it’s
still a surprise.</p>

<h2 id="how-do-you-check-that-youre-getting-charged">How do you check that you’re getting charged?</h2>

<p>View your billing usage at:
<a href="https://github.com/settings/billing">https://github.com/settings/billing</a></p>

<p>In the billing summary, look for the ‘Repositories’ section to identify which projects are incurring charges.</p>

<p><img src="/assets/images/posts/ghbilling/settings.png" alt="GitHub billing settings page showing repository usage." /></p>

<p>That tells me that my issue is showing up in the “mill” repository.</p>

<h2 id="how-do-you-fix-this">How do you fix this?</h2>

<p>Go to each of the projects you’re still getting billed for and modify the retention setting.</p>

<p>Navigate to the ‘Actions’ settings for each project and reduce the ‘Artifact and Logging’ retention period.</p>

<p><img src="/assets/images/posts/ghbilling/retention.png" alt="Github Project Artifacts and Logging Retention" /></p>

<p>It’s a bit crazy that this is set to 90 days. For a lot of runs or having a lot of large build artifacts, that can get
quite costly in a short period of time.</p>

<h2 id="also-while-youre-at-it">Also while you’re at it</h2>

<p>Disable Action Runs for any forks without approval. There’s no reason you should be billed for others that forked your
code.</p>

<p>Select the option:</p>

<blockquote>
  <p>Approval for running fork pull request workflows from contributors</p>
</blockquote>]]></content><author><name>shicks</name></author><category term="github-actions" /><category term="billing" /><category term="costs" /><category term="troubleshooting" /><category term="open-source" /><category term="devops" /><category term="automation" /><category term="github" /><category term="retention" /><category term="storage" /><category term="workflow" /><category term="ci-cd" /><category term="free-tier" /><category term="hidden-costs" /><category term="technical-debt" /><summary type="html"><![CDATA[You might be unknowingly paying for GitHub Actions even after your workflows have finished. Let’s set the stage for being me: you’ve forked a project, enabled the GitHub actions, stayed under your limit, and contributed a great change to an open source project. You’re all good right? Karma’s good, it’s great code, and you stayed at a low limit usage under the GitHub actions allowances.]]></summary></entry><entry><title type="html">gRPC: Up And Running (2020)</title><link href="https://theexceptioncatcher.com/2026/01/grpc-up-and-running-review/" rel="alternate" type="text/html" title="gRPC: Up And Running (2020)" /><published>2026-01-26T00:00:00+00:00</published><updated>2026-01-26T00:00:00+00:00</updated><id>https://theexceptioncatcher.com/2026/01/grpc-up-and-running-review</id><content type="html" xml:base="https://theexceptioncatcher.com/2026/01/grpc-up-and-running-review/"><![CDATA[<p><a href="/2026/01/getting-started-with-grpc-up-and-running/">In a previous post</a>, I shared a correction for
an early chapter of gRPC: Up and Running. It helped others who were
struggling with the initial gRPC server and client setup.</p>

<p>Now that I’ve finished reading it, here’s a quick review of <a href="https://search.worldcat.org/title/1137594283">“gRPC Up and Running” (2020) by Kasun Indrasiri and Danesh Kuruppu</a>.</p>

<p><strong>TL;DR:</strong> It does what it says it does on the tin. Would use to learn gRPC again.</p>

<h2 id="book-summary">Book Summary</h2>

<p>This book provides an introduction to gRPC, covering the underlying technologies and offering a broad overview of the
surrounding ecosystem. Once the basics of gRPC are established, the authors delve into the protocol’s inner workings,
its features, and important considerations for implementation.</p>

<h2 id="what-did-i-enjoy">What did I enjoy?</h2>

<p>I particularly appreciated the in-depth, visual examples that explained how gRPC functions over the network. The
challenges of network communication – such as avoiding packet fragmentation and ensuring speedy, ordered delivery – are
complex, and the authors’ visual approach made these concepts much easier to grasp.</p>

<p>I also appreciated the inclusion of health check instructions. While common practice for REST services, health checks
are often the first concern when deploying a new service, and it’s great to see them addressed in this context.</p>

<p>he final chapter effectively extended the discussion beyond the core technology, exploring how gRPC is used and extended
in real-world deployments.</p>

<p>The book’s structure and pacing were excellent. It introduces the technology clearly, allows you to experiment with a
simple example early on, and then progressively deepens the discussion, anticipating the questions you’ll likely have
during implementation. To the authors: Great work! There are many technical books that suffer on this front.</p>

<h2 id="what-could-have-been-better">What could have been better?</h2>

<p>An updated edition would be valuable. There have been many large scale changes with Protobufs and gRPC since the book
was written. Granted, this book was written in 2020, so the state of the book is completely understandable.</p>

<p>A more balanced perspective would have included a discussion of gRPC’s drawbacks and potential pain points. While a
detailed resolution isn’t necessary, pointing readers towards relevant discussions on these topics would be helpful.</p>

<p>It would have been interesting to see a discussion of experiences converting existing REST/SOAP services to gRPC, and
the resulting benefits or challenges.</p>

<p>Given the differences between gRPC and common RESTful APIs, a section on best practices for gRPC API design would have
been beneficial.</p>

<p>It would be helpful to understand any language-specific limitations or weaknesses in gRPC implementations. Even though
the content is older, this would give context to the history and language affinity for this language. I think the first
thought a person may have with this book is: Will a Go based gRPC server integrate against an Elixir based client.</p>

<p>Some of the code examples, while functional, felt a bit lengthy and could have benefited from more contextual
explanation to better illustrate their purpose.</p>

<h2 id="would-recommend-this-book">Would recommend this book:</h2>

<p>Yes.</p>

<p>If you’re looking to learn gRPC, I recommend this book. As the title suggests, it will help you get up and running
quickly. For those working through Chapter 2, you might find my previous post helpful for addressing a specific issue.</p>

<h2 id="resources">Resources</h2>

<ul>
  <li>Book link: <a href="https://search.worldcat.org/title/1137594283">“gRPC Up and Running” (2020) by Danesh Kuruppu</a></li>
  <li>My rewrite of the first <a href="https://github.com/monksy/getting-started-with-grpc">gRPC server and client example.</a></li>
  <li><a href="/2026/01/getting-started-with-grpc-up-and-running/">Explanation of the changes on the sample code.</a></li>
  <li>Great reference mentioned in the book: <a href="https://github.com/grpc-ecosystem/awesome-grpc?tab=readme-ov-file">Awesome-gRPC</a></li>
</ul>]]></content><author><name>shicks</name></author><category term="gRPC" /><category term="books" /><category term="reviews" /><category term="programming" /><category term="software development" /><category term="technology" /><category term="protobuf" /><category term="network programming" /><category term="microservices" /><category term="API design" /><category term="remote procedure call" /><category term="code review" /><category term="learning resources" /><category term="developer tools" /><category term="technical book" /><category term="computer science" /><category term="web services" /><category term="distributed systems" /><category term="performance optimization" /><category term="code examples" /><category term="errata" /><summary type="html"><![CDATA[In a previous post, I shared a correction for an early chapter of gRPC: Up and Running. It helped others who were struggling with the initial gRPC server and client setup.]]></summary></entry><entry><title type="html">Is This the Future of Software Development? (2026 Predictions)</title><link href="https://theexceptioncatcher.com/2026/01/predictions-for-development-practices-in-2026/" rel="alternate" type="text/html" title="Is This the Future of Software Development? (2026 Predictions)" /><published>2026-01-20T04:58:00+00:00</published><updated>2026-01-20T04:58:00+00:00</updated><id>https://theexceptioncatcher.com/2026/01/predictions-for-development-practices-in-2026</id><content type="html" xml:base="https://theexceptioncatcher.com/2026/01/predictions-for-development-practices-in-2026/"><![CDATA[<p>It’s the year of flying cars, robots, and all-digital lives. At least one of those things was a big focus at CES (
robotics). In the spirit of looking back in 2025, I thought I’d share a collection of things that might be considered,
explored, or should be abandoned in 2026.</p>

<h2 id="no-one-should-be-writing-interface-codedomain-models">No one should be writing interface code/domain models</h2>

<p>I’ve been thinking about this for years. Adapting to frameworks like DropWizard, Spring REST, Akka HTTP, and Play has
been a constant pain point. Much of the work done on the interface definition layer is repetitive rather than unique to
the business logic. I anticipate you might object: “What if my file upload spec requires a GET request?” These
deviations create unnecessary complexity, hinder documentation, and often lead to replacement with more maintainable
solutions after a few years. Many attempts to simplify this process have resulted in even more complicated and
specialized solutions, such as AWS AppSync. We once seemed to be moving towards more generic and consistent approaches,
but I’m not sure what happened. (See JAX-RS). Another example is Taplir. I’m still waiting to see if it gains traction,
though I’m very supportive of the project.</p>

<p>What should happen? Despite its imperfections, I believe gRPC offers a strong foundation as a generic definition
language that can be compiled into interface and domain generation libraries. With its extensions, it can support
integrations requiring REST-based communications.</p>

<p>OpenAPI is effective, but its generators lack consistency. This is a key weakness that could be addressed with more
robust testing and validation. Establishing a common language would allow us to verify and benchmark OpenAPI generator
outputs against the libraries they are intended to support.</p>

<h2 id="splitting-boundaries-in-large-systems-should-be-automateddata-driven">Splitting Boundaries in Large Systems Should be Automated/Data Driven</h2>

<p>Over the last 10+ years we’ve seen microservices being split apart and communication between them become incredibly
complex. In some cases, it’s been overkill, with overly fragmented services that shouldn’t have been split. We’ve also
seen a resurgence of monoliths in recent years.</p>

<p>What I believe will happen:</p>

<p>Decisions regarding service boundaries will be automated, identifying where splitting provides value and where it
doesn’t. Rather than deploying utilities as separate services, we may increasingly see them embedded directly into
dependent services. Reliable and consistent automation of this process requires a tool that leverages observable metrics
and service endpoint generation.</p>

<h2 id="code-is-focused-on-building-and-transformation-rather-than-formal-modeling-against-things">Code is focused on building and transformation rather than formal modeling against things</h2>

<p>Since the 1980s, with the rise of C++, object-oriented programming has emphasized modeling domain objects (which is
valuable) and assigning them inherent behaviors (deceptively limiting). More recent languages have demonstrated a
gradual shift away from strict OOP towards a functional style. As a fan of functional programming in Scala, I hope this
trend gains momentum.</p>

<p>Functional programming separates domain structure from behavior and transformation logic.</p>

<p>Where have we seen progress in this?</p>

<ul>
  <li><strong>Golang:</strong> Models domain objects through structures, and adding friction to attaching behvaior against them. Although,
the error model for Golang functions limits the ability to work with code in a functional manner.</li>
  <li><strong>Java</strong> The Oracle/Java Language Specification has embraced functional paradigms from Scala with features like the
Streams API, default methods, record classes (similar to case classes), and tools for writing more declarative
concurrent code (parallel streams).</li>
  <li><strong>JavaScript:</strong> Its lack of class-based inheritance encourages functional approaches.</li>
  <li><strong>Rust:</strong> Natively supports higher-order functions and is attracting engineers from the Scala community.</li>
</ul>

<p>The challenge lies in overcoming varying definitions and resistance to adopting new approaches. Many developers remain
attached to the traditional pattern of embedding behavior within domain objects.</p>

<h2 id="we-get-back-to-structured-testing">We get back to structured testing</h2>

<p>Giving LLMs ambitious tasks for large projects has been problematic. I think this will lead us in two directions:</p>

<p>Firstly, we may move to writing tests and letting the LLM generate the implementation code. This would give AI coding
systems the ability to validate, verify, and restructure the code. For this to be realized, the test/specification code
needs to become easier to humanly write. Given the current state of QA related technologies, frameworks, and systems, I
believe that will require a new language.</p>

<p>Secondly: Strongly structured testing techniques will be needed to verify AI code. AI can generate a lot of code, but it
isn’t always what you want. In a way, it’s like having an untrusted “gremlin” in your codebase. Testing will be needed
to verify on many levels for regression, acceptance, and reliability.</p>

<h2 id="we-finally-give-up-on-the-idea-of-forcing-real-time-decisions-on-services">We Finally Give up on the idea of forcing “Real time decisions” On Services</h2>

<p>Creating services that handle complex rules and data is expensive, and that expense increases when demanding real-time
performance. This gets worse every time a feature is added or the service is reused in a different context. What does
this mean? The push toward using queuing systems, asynchronous processing, and large-scale streaming platforms.</p>

<p>I anticipate two key shifts:</p>

<ol>
  <li>A clearer understanding of the appropriate roles and limitations of microservices and realistic performance
expectations</li>
  <li>A greater acceptance of communicating a longer processing status to users through the UI to build trust.
This shift is supported by the ongoing development of resources like the second edition of “Designing Data Intensive
Applications.”</li>
</ol>

<p>Additionally, this way of solving a problem ends up being cheaper to run with the right infrastructure (FaaS), and it’s
cheaper to maintain.</p>

<h2 id="libraries-become-comprehensive">Libraries become comprehensive</h2>

<p>I think this may be the most uncertain prediction here. Javascript and Python introduced a wave of self-promotion of
libraries that either riffed on other libraries, were forked for self-interest, or were overly specialized. We may
move back to a more established, reputable, and confirmed process of publishing reusable dependencies. Or not.
Golang, a popular language, has a completely decentralized, disorganized, and loose definition of dependency
management: it’s based on actual repositories of raw source code.</p>

<h2 id="ai-models">AI Models</h2>

<p>I don’t think AI models will get much better. I believe that they may become more space, memory, and parameter
efficient, and I believe they may get updated. The big next thing here is qualifying and validating the training data.
That’s going to be a murky and difficult path for LLMs. Additionally, it’s going to be worse if the data that the LLM is
trained on is Generated AI content.</p>

<h2 id="people-become-more-withdrawn-from-spaces-where-bot-based-content-exists">People become more withdrawn from spaces where bot based content exists</h2>

<p>We’re currently seeing spaces where large amounts of people gather being invaded by organizations and malicious
individuals to promote products and scams. Email and text messaging are being inundated with nonconsensual messages from
vendors we use. I would imagine this creates distrust by the customer and may cause more withdrawing and quiet
disconnects.</p>

<p>I’ve seen this with email and text marketing mostly through Square marketplace connected shops. I’ve never asked for
marketing from those companies and there seems to be no way to opt out of it from Square. Also, my understanding with
Facebook, it’s filled with distracting and non-asked for AI generated “content.”</p>

<h2 id="ai-slows-down-and-gets-better-focused-on-single-tasks">AI Slows down and gets better focused on single tasks</h2>

<p>AI is currently overhyped. There’s a lot of buzz around its potential to revolutionize everything and eliminate human
labor. We are starting to see the limitations of General AI and the practical constraints imposed by current models and
hardware. Hopefully, for software engineers, we’ll see better tools, integration, and ways to identify flaws in
languages, improvements in processes, and better ways to deliver more trustworthy solutions. I think that’s the
best-case scenario. Given the more likely scenario of: adapt or die, buy over build, and deny failure, I suspect we’ll
see a lot of turbulence and further large-scale technical disasters.</p>

<p>What can we expect from this? Hopefully, we’ll see specialized research involved in optimization and better definition
of tasks that are best fit for it.</p>

<h2 id="rust-continue-to-grow">Rust Continue to Grow</h2>

<p>2026 may be the year for Rust. Who knows. It looks like a great language, and I’m learning it. Coincidence? With the
economic downturn, there may be an increased desire to make systems more efficient to reduce cloud spend, and this may
be the answer. Who knows, I just hope it isn’t Go. (Go is currently experiencing turbulence and is deviating on its
original claims of “easy language” due to growing pains.)</p>

<h2 id="in-conclusion">In conclusion,</h2>

<p>Do I believe all of this will come to pass in 2026? No. However, I believe these considerations are worthwhile. Software
engineering is cyclical, and while past performance isn’t indicative of future results, I hope we can move towards more
communication, efficiency, and the creation of truly great software.</p>]]></content><author><name>shicks</name></author><category term="development" /><category term="software-engineering" /><category term="microservices" /><category term="grpc" /><category term="openapi" /><category term="functional-programming" /><category term="testing" /><category term="automation" /><category term="java" /><category term="kotlin" /><category term="rust" /><category term="golang" /><category term="javascript" /><category term="scala" /><category term="ai" /><category term="llm" /><category term="artificial-intelligence" /><category term="machine-learning" /><category term="dependency-management" /><category term="tech-predictions" /><category term="future-of-tech" /><category term="software-architecture" /><category term="code-generation" /><category term="asynchronous-processing" /><category term="data-driven-development" /><summary type="html"><![CDATA[It’s the year of flying cars, robots, and all-digital lives. At least one of those things was a big focus at CES ( robotics). In the spirit of looking back in 2025, I thought I’d share a collection of things that might be considered, explored, or should be abandoned in 2026.]]></summary></entry><entry><title type="html">Getting Started with gRPC: A Practical Example in Go</title><link href="https://theexceptioncatcher.com/2026/01/getting-started-with-grpc-up-and-running/" rel="alternate" type="text/html" title="Getting Started with gRPC: A Practical Example in Go" /><published>2026-01-12T00:00:00+00:00</published><updated>2026-01-12T00:00:00+00:00</updated><id>https://theexceptioncatcher.com/2026/01/getting-started-with-grpc-up-and-running</id><content type="html" xml:base="https://theexceptioncatcher.com/2026/01/getting-started-with-grpc-up-and-running/"><![CDATA[<p>I’ve recently been diving deeper into gRPC, having used it peripherally in another project. Wanting a solid foundation,
I explored several resources, ultimately
choosing <a href="https://search.worldcat.org/title/1137594283">“gRPC Up and Running” (2020) by Danesh Kuruppu</a>.
I initially tried <a href="https://search.worldcat.org/title/1415975460">“gRPC Microservices in Go (2023),”</a> but found it leaned
heavily into microservice architecture principles <em>before</em> explaining gRPC
itself. While the architecture discussion was interesting, it felt a bit distracting for someone that picked out the
book to learn gRPC.</p>

<h2 id="why-consider-grpc">Why Consider gRPC?</h2>

<p>gRPC is a high-performance, efficient protocol and interface definition language that enables you to generate server,
client, and data model components. While the protocol definition <em>is</em> strict (requiring careful ordering), this
contributes to its robustness and performance. Recent additions like “unknown fields” are beginning to address some of
the flexibility concerns.</p>

<p>There are several key benefits to using gRPC:</p>

<ul>
  <li><strong>Flexible Connection Models:</strong> Unlike REST, gRPC supports a wider range of connection options (unary, server
streaming, client streaming, and bidirectional streaming).</li>
  <li><strong>Code Generation:</strong> The Interface Definition Language (IDL) allows you to generate client and server code from a
single definition, reducing boilerplate and ensuring consistency. In 2020+ no one should be writing server side or
client side code from hand.</li>
  <li><strong>Tooling and Language Support</strong> Protobuffers (The underlying IDL) has a large ecosystem of support, usage, and
<a href="https://protobuf.dev/overview/">language support.</a></li>
  <li><strong>Performance:</strong> gRPC utilizes Protocol Buffers for serialization, resulting in a compact, binary format that’s faster
to transmit and parse compared to text-based formats like JSON.]**</li>
  <li><strong>REST Support</strong> If your client absolutely had to communicate with JSON, <a href="https://github.com/grpc-ecosystem/grpc-gateway">there’s a GRPC proxy that can do the
translation from a gRPC service to an REST compatible communication.</a></li>
</ul>

<h2 id="encountering-outdated-code">Encountering Outdated Code</h2>

<p>The second chapter of “gRPC Up and Running” introduces a sample product service that demonstrates adding and querying
products. Unfortunately, I found the provided code and tooling to be significantly outdated and difficult to compile.
Dependency issues and incompatibilities required substantial updates and distractions to get the example running.</p>

<p>To help others avoid these hurdles, I’ve created an updated and working version of the sample code, available
at: <a href="https://github.com/monksy/getting-started-with-grpc">monksy/getting-started-with-grpc</a>.</p>

<p>The original sample code can be found
here: <a href="https://github.com/grpc-up-and-running/samples/tree/master/ch02/productinfo/go">grpc-up-and-running/samples</a></p>

<h2 id="key-updates-to-the-sample-code">Key Updates to the Sample Code:</h2>

<ul>
  <li><strong>Automated The Code Generation:</strong> Added a <code class="language-plaintext highlighter-rouge">Makefile</code> to streamline the protocol buffer code generation process.</li>
  <li><strong><code class="language-plaintext highlighter-rouge">go vet</code> Integration:</strong> Incorporated <code class="language-plaintext highlighter-rouge">go vet</code> to improve code quality and catch potential errors. Fixing the line
<code class="language-plaintext highlighter-rouge">status.Errorf(codes.Internal, "Error while generating Product ID:", err)</code> with the formatter code <code class="language-plaintext highlighter-rouge">%v</code> at the end of
the message.</li>
  <li><strong>Local Module References:</strong>  Configured <code class="language-plaintext highlighter-rouge">go.mod</code> files to reference local modules, simplifying setup and removing the
need to publish to GitHub.</li>
  <li><strong>Updated Dependencies:</strong>  Updated gRPC dependencies to the latest versions.</li>
  <li><strong><code class="language-plaintext highlighter-rouge">go_package</code> Definition In the Protobufs:</strong> Added a <code class="language-plaintext highlighter-rouge">go_package</code> declaration to the <code class="language-plaintext highlighter-rouge">product_info.proto</code> file,
required for newer protobuf definitions.</li>
  <li><strong>Revised Protobuf Command:</strong> Updated the <code class="language-plaintext highlighter-rouge">protoc</code> command in the <code class="language-plaintext highlighter-rouge">Makefile</code> to reflect the newer expectations of the
protobuf compiler.</li>
  <li><strong>grpccurl Instructions:</strong> Added instructions to the <code class="language-plaintext highlighter-rouge">README</code> demonstrating how to verify the server is running using
<code class="language-plaintext highlighter-rouge">grpccurl</code>.</li>
  <li><strong>Created an output folder for the binaries</strong> The Makefile outputs all the binaries to <code class="language-plaintext highlighter-rouge">target/server|client/</code></li>
  <li><strong>GitLab CI Integration:</strong> Included a GitLab CI script for automated building and testing.</li>
</ul>

<hr />

<p>While “gRPC Up and Running” provides a good conceptual overview, the code examples are somewhat dated. I hope this
updated repository helps you get started quickly with gRPC. Feel free to contribute and share your feedback!</p>]]></content><author><name>shicks</name></author><summary type="html"><![CDATA[I’ve recently been diving deeper into gRPC, having used it peripherally in another project. Wanting a solid foundation, I explored several resources, ultimately choosing “gRPC Up and Running” (2020) by Danesh Kuruppu. I initially tried “gRPC Microservices in Go (2023),” but found it leaned heavily into microservice architecture principles before explaining gRPC itself. While the architecture discussion was interesting, it felt a bit distracting for someone that picked out the book to learn gRPC.]]></summary></entry><entry><title type="html">Best of 2025: Part 3</title><link href="https://theexceptioncatcher.com/2026/01/best-of-2025-travel-and-cultural/" rel="alternate" type="text/html" title="Best of 2025: Part 3" /><published>2026-01-06T18:00:00+00:00</published><updated>2026-01-06T18:00:00+00:00</updated><id>https://theexceptioncatcher.com/2026/01/best-of-2025-travel-and-cultural</id><content type="html" xml:base="https://theexceptioncatcher.com/2026/01/best-of-2025-travel-and-cultural/"><![CDATA[<p>The theme of this part is Cultural and Travel Experiences. These are some of the non-work/technical related things
that I found/did/stood out last year.</p>

<h2 id="travel">Travel</h2>

<h3 id="international">International</h3>

<p>As of writing this (January 1st, 2026), last year took me to Latvia, Taiwan, and Indonesia (Bali). By far, Taiwan was my
favorite.</p>

<p><img src="/assets/images/posts/bestof/taipei.jpg" alt="Taipei From The Hotel Room" /></p>

<p>The people were exceptionally friendly, public transportation, TRA, and HSR were outstanding, and nearly every meal was
incredible. More than anything, Taiwan felt easy to exist in. It felt like you could participate in their culture,
events, activities, without having to fully buy into their commerces or communities. Want to go to a baseball game (
that’s big there), it’s cheap compared to an MLB game. Need to escape to the mountains for a day off, you’ve got buses
to Wulai. Unlike in the US and other countries, I didn’t feel like I was locked in to some forced smartphone app to do
everything. I could reserve what I wanted to do online, and go in person to pick up my tickets. I felt free to explore,
interact, wander, and simply enjoy where I was.</p>

<p>Across two trips, I visited Tainan, Taipei, Alishan National Scenic Area, and Taitung. My first trip was a solo visit in
April, and later in July I managed to squeeze in a short three-day stopover. Even that brief return trip I was still
able to enjoy my time there.</p>

<p>Taiwan has officially earned a permanent spot on my “return often” list. Even compared to Japan.</p>

<hr />

<h3 id="domestic">Domestic</h3>

<p>I usually avoid domestic travel — the cost-to-experience ratio often just isn’t there — but I did have two standout
trips this year.</p>

<p><strong>Amtrak: Seattle → Chicago (Empire Builder, Eastbound)</strong></p>

<p>I rode the reverse route of the Empire Builder primarily to finally see Glacier National Park, which I missed on my
first ride in 2021. While the trip wasn’t quite as an adventure as my original westbound run, Glacier national park was
good to see. Additioanlly it was good to see the border between Minnesota and Wisconsin. (Also missed on the westbound
route due to it being dark) Some of the diminished experience likely had to do with the government shutdown at the time
but even so, it was still worth it.</p>

<hr />

<p><strong>Lake Wisconsin</strong></p>

<p>This trip ended up being quietly recharging because it introduced me to kayaking. I didn’t expect it to stick, but it
really did — and once the weather warms up, I plan to lean much harder into it.</p>

<h2 id="culture">Culture</h2>

<h3 id="music">Music</h3>

<p>I saw a lot of shows this year — including the Oasis reunion — but three stood far above the rest:</p>

<p><strong>Russian Circles</strong> — Easily the most powerful and enjoyable live performance I saw all year. It wasn’t the most
energetic show I saw, but the light show and music made it enjoyable, immersive, and perfect.</p>

<p><strong>Mogwai</strong> This show brings a lot of their long time fans. I didn’t have a strong feeling of the show. But it helped to
appreciate their music more.</p>

<p><strong>YOB</strong>  Very good, but didn’t leave quite the same lasting impression as the two above.</p>

<hr />

<h2 id="comedy">Comedy</h2>

<p>Three comedians really stood out:</p>

<p><strong>Ian Fidance</strong> — Incredible stage presence and raw energy.</p>

<p><strong>Geoffrey Asmus</strong> — Loud, belligerent, absurd — in the best way.</p>

<p>A Philly-based comic whose name I tragically forgot — Completely unhinged, chaotic, and hilarious. This was in the
earlier months in 2025 at Zanies. The show was nearly empty, but he killed.</p>

<p>Interestingly, the more “industry-backed” shows — especially those tied to large brands or things like Kill Tony —
consistently underperformed and disappointed. The smaller, less polished, more chaotic shows ended up being far better experiences.</p>

<hr />

<h2 id="food">Food</h2>

<p>Two meals absolutely dominated the year:</p>

<p><a href="https://gajahputihbali.com/"><strong>Gajah Putih (Ubud, Bali)</strong></a> — Incredible food, excellent service, and a beautifully
executed concept. The entire experience
felt curated in the best way.</p>

<p><a href="https://maps.app.goo.gl/zQwACHid91zw2SVL8"><strong>難得一面 Beef Noodles (Taipei) —
青花椒 / 大紅袍、超濃蕃茄、麻辣牛肉麵、乾拌麵、重磅蛤蜊麵</strong></a>
I didn’t go here for the beef noodles. But the garlic noodles they had were spicy, warming, cheap, and comforting. It’s
exactly what I wanted after a hot springs soak in Wulai. I only managed to visit once while they were open, and I will seek them out the next time I’m in Taiwan.</p>

<hr />

<h2 id="museums">Museums</h2>

<p>Surprisingly, museums didn’t leave much of an impression this year. I do recall going to a modern art museum in Tainan.</p>

<p>I’ve also found myself increasingly discouraged by the shift toward mandatory early online ticketing, which has quietly
drained a lot of spontaneity and enjoyment from city exploration.</p>]]></content><author><name>shicks</name></author><category term="travel" /><category term="year-in-review" /><category term="best-of-2025" /><category term="taiwan" /><category term="bali" /><category term="latvia" /><category term="solo-travel" /><category term="amtrak" /><category term="empire-builder" /><category term="glacier-national-park" /><category term="kayaking" /><category term="live-music" /><category term="concerts" /><category term="comedy" /><category term="food" /><category term="beef-noodles" /><category term="ubud" /><category term="taipei" /><category term="reflection" /><category term="lifestyle" /><summary type="html"><![CDATA[The theme of this part is Cultural and Travel Experiences. These are some of the non-work/technical related things that I found/did/stood out last year.]]></summary></entry><entry><title type="html">Best of 2025: Part 2</title><link href="https://theexceptioncatcher.com/2026/01/best-of-2025-self-care-and-non-technical/" rel="alternate" type="text/html" title="Best of 2025: Part 2" /><published>2026-01-05T18:00:00+00:00</published><updated>2026-01-05T18:00:00+00:00</updated><id>https://theexceptioncatcher.com/2026/01/best-of-2025-self-care-and-non-technical</id><content type="html" xml:base="https://theexceptioncatcher.com/2026/01/best-of-2025-self-care-and-non-technical/"><![CDATA[<p>The theme of this part is Self Care and Non-Technical things. These are some of the non-work/technical related things
that I found/did/stood out last year.</p>

<hr />

<h3 id="building-an-exercise-routine">Building an Exercise Routine</h3>

<p>One of the biggest quality-of-life improvements I made this year was committing to a real exercise routine. It
noticeably increased my strength and had a surprisingly positive impact on my overall mental well-being. Unfortunately,
an injury sidelined me for a few months, which was frustrating. Tracking my activity turned out to be essential; seeing
tangible progress made it far easier to stay motivated.</p>

<hr />

<h3 id="joining-sports-leagues">Joining Sports Leagues</h3>

<p>Alongside the exercise routine, I joined a few sports leagues and ended up making some genuinely great friends. It
became one of my favorite ways to stay active and social at the same time. My WhirlyBall team, in particular, turned
into a highlight of my week—it didn’t feel like “exercise,” it felt like fun.</p>

<hr />

<h3 id="walking--exploring-trails">Walking &amp; Exploring Trails</h3>

<p>I spent a good amount of time walking and exploring trails this year, mostly using AllTrails. While it helped me
discover new places, its increasing number of paywalled tiers has made it feel like less of a good value. It is fairly
limited on the content on the platform and the lack of users giving feedback on the platform. There are some promising
open-source alternatives out there that I haven’t fully tested yet, but they’re definitely on my radar.</p>

<p>Still, I managed to explore trails around Chicago, Wisconsin, and even Taiwan. Getting outside, unplugging, and just
being present turned out to a great way to disconnect and reset my mind.</p>

<hr />

<h3 id="meditation--tea">Meditation &amp; Tea</h3>

<p>This might be the most meaningful habit I picked up all year. Meditation became my way to quiet the noise, slow things
down, and re-center myself. Around the same time, I fell completely in love with tea. Tea was not a new thing to me,
I regularly consumed black tea with meals (as is culturally normal), but it was the discovery of the high quality
Oolongs and high mountain varieties I found in Taiwan. It delivers this deeply calming, almost heady relaxation that
feels like a gentle reset button for your nervous system.</p>

<p>The Calm app played a big role in making meditation approachable and consistent. Together, meditation and tea became a
small daily ritual that I genuinely look forward to.</p>

<h2><img src="/assets/images/posts/bestof/post-hotspring-tea.jpg" alt="Taipei From The Hotel Room" /></h2>

<h3 id="learning-to-take-breaks">Learning to Take Breaks</h3>

<p>This one has been harder than I’d like to admit. I’m not naturally great at stepping away, but I’ve slowly started to
build better habits around taking real breaks.</p>

<hr />

<h3 id="reading">Reading</h3>

<p>I’ve also been reading more than usual this year, largely thanks to the Meebook e-reader I picked up. Being able to
access my entire library on a high-quality screen. I couldn’t imagine using a Kindle which would lock me into Amazon’s
restrictive and sometimes temporary ecosystem. It’s made reading far more accessible and enjoyable. It lowered the
friction enough that reading became something I actually do again, not just something I intend to do.</p>

<hr />

<h3 id="audiobooks">Audiobooks</h3>

<p>Audiobooks ended up being a surprisingly rewarding activity. This didn’t take off until I installed and built up
an <a href="https://www.audiobookshelf.org/">Audiobookshelf</a> server to manage audiobooks and podcasts. I made it through five or
six non-technical books this year, far more than I normally would, and it opened the door to titles I probably wouldn’t
have had the attention span for otherwise. <a href="https://search.worldcat.org/title/Project-Hail-Mary/oclc/1280097656">Project Hail Mary</a>
and the <a href="https://search.worldcat.org/title/1528905728">Bobiverse series</a> were standouts, and they made walks, chores,
and downtime feel richer and more engaging.</p>]]></content><author><name>shicks</name></author><category term="self-care" /><category term="personal-growth" /><category term="wellness" /><category term="mental-health" /><category term="mindfulness" /><category term="meditation" /><category term="tea" /><category term="exercise" /><category term="fitness" /><category term="injury-recovery" /><category term="sports-leagues" /><category term="whirlyball" /><category term="walking" /><category term="hiking" /><category term="trails" /><category term="reading" /><category term="audiobooks" /><category term="digital-minimalism" /><category term="slow-living" /><category term="life-optimization" /><summary type="html"><![CDATA[The theme of this part is Self Care and Non-Technical things. These are some of the non-work/technical related things that I found/did/stood out last year.]]></summary></entry><entry><title type="html">Best Of 2025</title><link href="https://theexceptioncatcher.com/2026/01/best-of-2025-technical-and-buying/" rel="alternate" type="text/html" title="Best Of 2025" /><published>2026-01-02T05:38:00+00:00</published><updated>2026-01-02T05:38:00+00:00</updated><id>https://theexceptioncatcher.com/2026/01/best-of-2025-technical-and-buying</id><content type="html" xml:base="https://theexceptioncatcher.com/2026/01/best-of-2025-technical-and-buying/"><![CDATA[<p>I haven’t done a “best of” list on my blog, but I’ve seen a lot of interesting posts from other bloggers. This is my review of 2025 and what I personally enjoyed or things that stuck out to me. This will be a highly focused, but not a comprehensive, list.</p>

<p>Without further ado:</p>

<h2 id="technical">Technical</h2>

<p><strong>gRPC</strong> has been an interesting technology to dive into. I’ve known about it for years, and I’ve worked with technologies that it incorporates (Protobufs). But it’s great to learn about it’s features and the problems it attempts to solve. I’m hoping to publish a blog post on getting started with gRPC soon.</p>

<hr />

<p><strong>K6:</strong> I’ve said it many times, and I stand by the statement: JavaScript is terrible.</p>

<p>However, a place where it does work supprisingly well is as feature tests for HTTP based services. I’ve had an easier time writing feature tests with K6 and would consider doing this as the default way to write feature tests for services.</p>

<hr />

<p><strong>Gitlab Actions</strong> I’ve been reluctantly moving to an Actions-based system for my CI/CD work. They work reasonably well, although getting my GitLab runners set up and running took a fair amount of effort.</p>

<p>The more I work with actions, the less I rely on my Jenkins instance. (Which is good for maintance reasons)</p>

<hr />

<p><strong>Layering</strong> This is a technique where you can build foundation pieces using Git, GitLab/GitHub, and new libraries. I may discuss this technique in more detail in a later blog post. But this allowed me to learn new frameworks, create POCs for problems and tools.</p>

<p>I may discuss this in more detail in a future post, but this approach has allowed me to:</p>
<ul>
  <li>Learn new frameworks</li>
  <li>Rapidly create proof-of-concepts</li>
  <li>Experiment with tools and architectures more safely</li>
</ul>

<hr />

<p><strong>Artificial Intelligence with LLMs</strong></p>

<p>LLMs have probably been one of the biggest contributors to my technical growth this year.</p>

<p>They’ve helped me:</p>

<ul>
  <li>Summarize online research</li>
  <li>Troubleshoot technical and non-technical problems</li>
  <li>Prepare for and practice interviews</li>
  <li>Proofread my writing</li>
</ul>

<p>I even built my own private LLM setup using Ollama and self-hosted models.</p>

<p>I was very reluctant to jump on this bandwagon due to how aggressively AI tooling was forced at a former job: including stack-ranking employees and forced attrition based on GitHub Copilot training participation and token usage. That experience left a bad taste, but using LLMs on my own terms has been genuinely transformative.</p>

<p>Favorite models:</p>

<ul>
  <li>Qwen3: Planning</li>
  <li>Gemma3: writing related tasks</li>
  <li>GPT5: Adapting code in respect of it’s surrounding codebase.</li>
  <li>Qwen2.5: Coder</li>
</ul>

<hr />

<p><strong>Building my own router</strong>
Building my own router has been both extremely educational and occasionally punishing, but ultimately very rewarding.
I moved from a consumer all-in-one router to a fully featured OPNsense-based setup. I now run:</p>

<ul>
  <li>Custom VPNs</li>
  <li>Advanced routing rules</li>
  <li>Multiple segmented networks</li>
  <li>Caching services</li>
  <li>Private DNS</li>
</ul>

<p>And honestly? I love it.</p>

<h2 id="what-ive-bought-that-stood-out">What I’ve bought that stood out</h2>

<p><strong>Soundcore Earbuds (Anker)</strong></p>

<p>I lost the charging case for my Sony noise-cancelling earbuds and later discovered that if you lose the case, you have to re-pair the earbuds to a replacement. On top of that, a new case costs well over $100.</p>

<p>Given that outrageous price and the fact that a firmware bug significantly degraded the battery life of the earbuds themselves (with no recall… thanks, Sony) I decided to try the Soundcore earbuds from Anker instead.</p>

<p>For earbuds, I’ve been genuinely thrilled with them and plan to stick with them going forward.</p>

<p><strong>Zigbee devices</strong></p>

<p>As I expanded my home automation setup, I found Zigbee devices to be fantastic to work with.
I haven’t gone too deep into complex automations yet, but it’s incredibly nice to have devices that can join your network (No stupid, noisy vendor app needed), and report sensor information with ease.
This has really helped in getting my smart home setup feel easier to use, and more informative.</p>]]></content><author><name>shicks</name></author><category term="best-of-2025" /><category term="year-in-review" /><category term="personal-tech" /><category term="developer-life" /><category term="self-hosting" /><category term="homelab" /><category term="home-automation" /><category term="zigbee" /><category term="opnsense" /><category term="networking" /><category term="privacy" /><category term="open-source" /><category term="gRPC" /><category term="ci-cd" /><category term="gitlab" /><category term="llms" /><category term="artificial-intelligence" /><category term="productivity" /><category term="earbuds" /><category term="smart-home" /><summary type="html"><![CDATA[I haven’t done a “best of” list on my blog, but I’ve seen a lot of interesting posts from other bloggers. This is my review of 2025 and what I personally enjoyed or things that stuck out to me. This will be a highly focused, but not a comprehensive, list.]]></summary></entry><entry><title type="html">Beyond Single Commands: SDKMan’s Hidden Environment File Feature</title><link href="https://theexceptioncatcher.com/2025/09/sdkman-environment-files/" rel="alternate" type="text/html" title="Beyond Single Commands: SDKMan’s Hidden Environment File Feature" /><published>2025-09-25T00:00:00+00:00</published><updated>2025-09-25T00:00:00+00:00</updated><id>https://theexceptioncatcher.com/2025/09/sdkman-environment-files</id><content type="html" xml:base="https://theexceptioncatcher.com/2025/09/sdkman-environment-files/"><![CDATA[<p>SDKMan is a tool designed to help developers manage JDK versions within their development environment. Born from the
GVM (Groovy Version Manager), it has evolved into a comprehensive SDK versioning system supporting many languages within
the Java ecosystem.</p>

<p>For most users, SDKMan provides basic CRUD (Create, Read, Update, Delete) operations for SDKs on their system – listing,
removing, installing, and more. You can find a full overview of its usage here:  <a href="https://sdkman.io/usage/">SDKMan.io: Usage</a></p>

<p>However, I recently discovered a feature that I think is particularly cool: SDKMan environment files. These files
function similarly to Python virtual environments, allowing you to define and manage SDK versions on a per-project
basis. When you are working with other engineers, with different development environments, this is a great way to get
consistency on everyone’s development environment.</p>

<p>Here’s a sample environment file, including support for JDK 25 (Corretto) and SBT:</p>

<p>File (in your project): <code class="language-plaintext highlighter-rouge">.sdkmanrc</code></p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">java</span><span class="o">=</span>25-amzn
<span class="nv">sbt</span><span class="o">=</span>1.11.6
</code></pre></div></div>

<p>Execute the command: <code class="language-plaintext highlighter-rouge">sdk env install</code> The tool will kick off downloads, if it hasn’t already, and will manage your
environment in your shell.</p>

<p>How does this work? SDKMan downloads the SDK versions to its  <code class="language-plaintext highlighter-rouge">~/.sdkman/candidates/</code> folder. It then updates your <code class="language-plaintext highlighter-rouge">PATH</code> to
prioritize the environment contained within that folder. This ensures that when you run sbt or java in this environment,
the versions defined in the environment file are preferred.</p>

<p>Even better, this environment persists across sessions whenever you enter the directory – if you have <code class="language-plaintext highlighter-rouge">sdkman_auto_env</code>
set to <code class="language-plaintext highlighter-rouge">true</code> (this value is configured in  <code class="language-plaintext highlighter-rouge">~/.sdkman/etc/config</code>).</p>]]></content><author><name>shicks</name></author><category term="SDKMan" /><category term="Java" /><category term="SDK" /><category term="Development" /><category term="Version Management" /><category term="Environment Management" /><category term="Virtual Environments" /><category term="Project Management" /><category term="Tooling" /><category term="Developer Tools" /><category term="Command Line Interface (CLI)" /><category term="Automation" /><category term="Productivity" /><category term="Groovy" /><category term="SBT" /><category term="Corretto" /><category term="OpenJDK" /><category term="Configuration Management" /><summary type="html"><![CDATA[SDKMan is a tool designed to help developers manage JDK versions within their development environment. Born from the GVM (Groovy Version Manager), it has evolved into a comprehensive SDK versioning system supporting many languages within the Java ecosystem.]]></summary></entry><entry><title type="html">Finding The Owner of An Open Port</title><link href="https://theexceptioncatcher.com/2025/09/finding-the-owner-of-an-open-port/" rel="alternate" type="text/html" title="Finding The Owner of An Open Port" /><published>2025-09-18T00:00:00+00:00</published><updated>2025-09-18T00:00:00+00:00</updated><id>https://theexceptioncatcher.com/2025/09/finding-the-owner-of-an-open-port</id><content type="html" xml:base="https://theexceptioncatcher.com/2025/09/finding-the-owner-of-an-open-port/"><![CDATA[<p>Under Linux, and BSD systems, in order to find out the owner of a port, the first advice usually given is to use:</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>lsof <span class="nt">-i</span> :portnumber
</code></pre></div></div>

<p>For example when checking for the SSH port, you’ll get the following results:</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>lsof <span class="nt">-i</span> :22
COMMAND    PID   USER FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd      1406   root 6u  IPv4   6746      0t0  TCP <span class="k">*</span>:ssh <span class="o">(</span>LISTEN<span class="o">)</span>
</code></pre></div></div>

<p>You’ll get information on the command that’s running, the process ID, the user it’s runing as, and many other networking
related details.</p>

<h2 id="but-lsof-returned-nothing">But lsof Returned nothing!</h2>

<p>I had this issue after installing k3s on a local machine. The application that was using port 80 no longer responded to
the port. Even restarting the application, the port still didn’t respond how I expected.</p>

<p>Stopping the application, the port still remained considered to be open by <code class="language-plaintext highlighter-rouge">nmap.</code> What happened? I pulled out the trust
<code class="language-plaintext highlighter-rouge">lsof</code>, but that returned no results. Quite a frustrating situation.</p>

<p>What was the issue?</p>

<p>Check to see if the firewall is forwarding the port. If the firewall forwards the port to another port locally, no
matter what you have listening to port :80 will bind to the port. If K3S has root access on installs, it will try to
take over port 80 to forward to another port it operates on. In this situation, <code class="language-plaintext highlighter-rouge">lsof -i</code> is correct, theres no PID
associated with that port.</p>

<p>I was lucky that disabling k3s reverted the rule. However, if I wanted to verify this behavior, consider the
following <a href="https://unix.stackexchange.com/a/683779">stackoverflow</a> answer to view the rules.</p>]]></content><author><name>shicks</name></author><category term="linux" /><category term="networking" /><category term="troubleshooting" /><category term="lsof" /><category term="ports" /><category term="port-ownership" /><category term="k3s" /><category term="firewall" /><category term="iptables" /><category term="port-forwarding" /><category term="system-administration" /><category term="server-management" /><category term="command-line" /><category term="diagnostics" /><category term="security" /><category term="nmap" /><category term="process-id" /><category term="unix" /><category term="bsd" /><summary type="html"><![CDATA[Under Linux, and BSD systems, in order to find out the owner of a port, the first advice usually given is to use:]]></summary></entry></feed>