Skip to content

fix: don't panic when a Let's Encrypt request fails - #1046

Merged
jmattheis merged 1 commit into
gotify:masterfrom
NotAFlightRisk:fix-letsencrypt-transport-error
Sep 9, 2026
Merged

fix: don't panic when a Let's Encrypt request fails#1046
jmattheis merged 1 commit into
gotify:masterfrom
NotAFlightRisk:fix-letsencrypt-transport-error

Conversation

@NotAFlightRisk

Copy link
Copy Markdown

A refused connection to the ACME server can take the whole process down, not just the renewal that hit it.

LoggingRoundTripper.RoundTrip reads resp.StatusCode before it looks at err. A dial failure, a DNS miss, a cancelled context or the clients own 60s timeout all come back as a nil response with an error, so that first line panics and the else if err != nil branch below it never gets its turn.

Point an acme.Client at a directory URL that refuses the connection, through that transport, and you get:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10]

github.com/gotify/server/v3/runner.(*LoggingRoundTripper).RoundTrip
	runner/runner.go:111

With the branches swapped it logs the line that branch was written for and hands the error back:

{"level":"warn","client":"Let's Encrypt","error":"dial tcp 127.0.0.1:1: connect: connection refused","method":"GET","url":"https://127.0.0.1:1/directory","message":"Request failed"}

Which of those you get depends on who made the request. During a handshake net/http recovers it, so you lose that connection and a stack trace lands in the log. Renewal is the bad one: autocert schedules it with time.AfterFunc, so the callback is a bare goroutine with nothing to recover it, and the server exits.

The diff just moves the error branch to the front, all three log lines are unchaged. There was no test file under runner/ at all, so theres one now covering the nil-response case.

@NotAFlightRisk
NotAFlightRisk requested a review from a team as a code owner September 8, 2026 00:14
@codecov

codecov Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.50000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 76.04%. Comparing base (d6a01f0) to head (553f665).

Files with missing lines Patch % Lines
runner/runner.go 87.50% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1046      +/-   ##
==========================================
+ Coverage   75.77%   76.04%   +0.27%     
==========================================
  Files          66       66              
  Lines        3620     3620              
==========================================
+ Hits         2743     2753      +10     
+ Misses        666      655      -11     
- Partials      211      212       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jmattheis
jmattheis force-pushed the fix-letsencrypt-transport-error branch from 9b5a807 to 553f665 Compare September 9, 2026 18:59

@jmattheis jmattheis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@jmattheis
jmattheis enabled auto-merge September 9, 2026 19:00
@jmattheis
jmattheis added this pull request to the merge queue Sep 9, 2026
Merged via the queue into gotify:master with commit 0c24eda Sep 9, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants