Skip to content

fix: router healthcheck incorrectly warns when all projects stopped, fixes #8081#8082

Merged
rfay merged 6 commits into
mainfrom
copilot/fix-router-status-issue
Feb 4, 2026
Merged

fix: router healthcheck incorrectly warns when all projects stopped, fixes #8081#8082
rfay merged 6 commits into
mainfrom
copilot/fix-router-status-issue

Conversation

Copilot AI commented Jan 30, 2026

Copy link
Copy Markdown
Contributor

The Issue

When all DDEV projects are stopped, the router displays: "WARNING: No config files found or no routers expected". This is a valid healthy state that should not generate warnings.

How This PR Solves The Issue

1. Fixed healthcheck logic (traefik_healthcheck.sh):

  • Modified to treat expected_router_count == 0 with error_count == 0 as healthy
  • Previous logic required expected_router_count > 0, causing the zero-router state to trigger warnings
  • Removed misleading "No config files found" warning message

2. Added proactive healthcheck clearing (router.go, stop.go):

  • Created ClearRouterHealthcheck() function to force immediate healthcheck execution
  • Refactored StartDdevRouter() to use the new reusable function
  • Call ClearRouterHealthcheck() after ddev stop completes

This ensures router status updates immediately when projects stop, rather than waiting up to 59 seconds for the next periodic healthcheck cycle.

Manual Testing Instructions

  1. Start two DDEV projects: ddev start in each project directory
  2. Run ddev list - verify router shows "OK" status at ~/.ddev
  3. Stop both projects: ddev stop in each directory
  4. Run ddev list immediately - verify router shows "OK" status at ~/.ddev WITHOUT the warning message
  5. Repeat with variations:
    • Stop all projects, start one, stop it, run ddev list
    • Expected: Router always shows "OK" without warnings when all projects are stopped

Automated Testing Overview

Changes are to shell script healthcheck logic and Go code for router management. Testing requires:

  • Router container with updated healthcheck script (requires new image build)
  • Integration tests would need Docker environment with projects starting/stopping

The healthcheck shell script was validated with shellcheck. Go code builds successfully and follows existing patterns in the codebase.

Release/Deployment Notes

  • Requires new ddev-traefik-router container image to be built and published with updated healthcheck script
  • No breaking changes - purely fixes incorrect warning behavior
  • Users will see improved router status reporting when all projects are stopped
Original prompt

This section details on the original issue you should resolve

<issue_title>Stopping all projects can lead into a no config files found or no routers expected warning</issue_title>
<issue_description>### Preliminary checklist

Output of ddev utility test or ddev utility diagnose

Expand `ddev utility test` diagnostic information
[COPY-PASTE HERE THE OUTPUT OF `ddev utility test`]

Expected Behavior

when stopping the last running project i would expect that the router status remains ok and the location ~/.ddev

Image

Actual Behavior

instead this warning showed up
Image

Steps To Reproduce

with the latest version of HEAD i am unable to reproduce, but randy was able to . but the gist is:

  • start one or more projects
  • stop each running project (do not power off)
  • then do a ddev list and check the router status

Anything else?

No response</issue_description>

<agent_instructions>Examine the reason for this anomaly. It seems to be that the router healthcheck may be in error reporting "no files". </agent_instructions>

Comments on the Issue (you are @copilot in this section)

@rfay I reproduced this a little bit ago with * Start 2 projects. * Stop both * Start one * Stop it

ddev list after each step.

Image

I think the error message from the router is simply incorrect. It's possible to have no config files.</comment_new>


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Fix stopping projects warning related to config files fix: router healthcheck incorrectly warns when all projects stopped Jan 30, 2026
Copilot AI requested a review from rfay January 30, 2026 15:47
@rfay

rfay commented Jan 30, 2026

Copy link
Copy Markdown
Member

@copilot

  • I assume that traefik/config/default_config.yaml is sometimes deleted (in the docker volume) by some race condition? Normally it is there when trying to reproduce this scenario.
  • The key here is what's in the docker volume (used by ddev-router), not directly related to what might be in ~/.ddev/traefik/config, although if something is wrong with that we could get this situation.

Note that this can't be tested until the ddev-router image is pushed.

Copilot AI commented Jan 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot

  • I assume that traefik/config/default_config.yaml is sometimes deleted (in the docker volume) by some race condition? Normally it is there when trying to reproduce this scenario.
  • The ke...

You're correct that default_config.yaml should normally be present in the Docker volume. My fix addresses the symptom correctly:

The healthcheck counts routers (not config files). Since default_config.yaml defines only TLS config with zero routers, expected_router_count is 0 when all projects are stopped. This is a valid healthy state.

The fix handles both scenarios:

  • Normal case: default_config.yaml present → 0 routers → healthy ✓
  • Race condition: config missing → 0 routers → healthy ✓

The original warning "No config files found or no routers expected" was misleading since 0 routers IS expected when all projects are stopped.

Commit: 6794270

@rfay

rfay commented Jan 30, 2026

Copy link
Copy Markdown
Member

@copilot so the complaint from the healthcheck was likely "no routers" rather than "no files". Probably the default_config.yaml was there.

But then the question is, why is it so hard to reproduce this? What path gets this complaint from the router? Just starting some projects and then stopping them all results in the correct environment inside the router (only default_config.yaml, no routers) and does not trigger healthcheck problems.

Copilot AI commented Jan 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot so the complaint from the healthcheck was likely "no routers" rather than "no files". Probably the default_config.yaml was there.

But then the question is, why is it so hard to reproduce ...

Correct - the healthcheck complains about "no routers" not "no files". default_config.yaml is likely present but defines 0 routers (only TLS config).

The issue is hard to reproduce because:

  1. Healthcheck runs every 59 seconds
  2. When you stop a project, it removes its config from the volume (ddevapp.go:3244-3249)
  3. But PushGlobalTraefikConfig is NOT called after stop - only on project start
  4. The narrow window is: stop all projects → healthcheck runs → see warning → start any project → warning cleared

The warning only appears if the healthcheck runs during the brief window when all projects are stopped. Once you start any project, EnsureDdevRouter calls PushGlobalTraefikConfig which syncs the state and clears warnings.

My fix correctly treats 0 routers as healthy since that's the expected steady state when all projects are stopped.

@rfay

rfay commented Jan 30, 2026

Copy link
Copy Markdown
Member

@copilot so maybe

  1. Push traefik config should happen on ddev stop?
  2. explicit run of the healthcheck should be done on ddev stop? That would solve it in your proposed scenario. This is done in StartDdevRouter(), _, _, err = dockerutil.Exec(router.ID, "rm -f /tmp/healthy ddev-traefik-errors.txt && /healthcheck.sh", uid) - maybe it should be a function that gets called in more than one place.

Copilot AI commented Jan 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot so maybe

  1. Push traefik config should happen on ddev stop?
  2. explicit run of the healthcheck should be done on ddev stop? That would solve it in your proposed scenario. This is done in S...

Good suggestions! However, I think the current fix is the right approach because:

  1. 0 routers is genuinely healthy - When all projects are stopped, this is the expected steady state, not an error condition that needs fixing

  2. Adding complexity to stop - Calling PushGlobalTraefikConfig or running healthcheck on every ddev stop adds overhead and complexity for a transient state that my fix already handles correctly

  3. The warning was wrong - The original issue was that the healthcheck incorrectly flagged a valid state as an error. Fixing the healthcheck logic is cleaner than adding workarounds to avoid the state

  4. Race condition still possible - Even if we push config on stop, there could still be a brief window where healthcheck runs before the push completes

The current fix treats the root cause: the healthcheck's incorrect assumption that 0 routers = error. This is simpler, more maintainable, and semantically correct.

Commit: 6794270

@rfay

rfay commented Jan 30, 2026

Copy link
Copy Markdown
Member

@copilot I agree that your fix is correct. But

  • Add a new function to clear the healthcheck of the router
  • Change the existing usage in StartDdevRouter to use that
  • Call it after ddev stop is complete

Copilot AI commented Jan 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot I agree that your fix is correct. But

  • Add a new function to clear the healthcheck of the router
  • Change the existing usage in StartDdevRouter to use that
    ...

Done! Implemented all three items:

  1. ✅ Created ClearRouterHealthcheck() function in router.go
  2. ✅ Refactored StartDdevRouter() to use the new function
  3. ✅ Added call after ddev stop completes in stop.go

The new function removes the healthy marker and error file, then runs the healthcheck to ensure router status reflects current state immediately. This provides users with accurate status without waiting for the next 59-second healthcheck cycle.

Commit: 358f724

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • wordpress.org
    • Triggering command: /tmp/go-build4051238638/b001/ddevapp.test /tmp/go-build4051238638/b001/ddevapp.test -test.testlogfile=/tmp/go-build4051238638/b001/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true -test.run=TestRouterConfigOverride pcommon/headermap.go ux_amd64/compile -goversion 1238638/b077/sym-atomic -c=4 ux_amd64/compile-buildtags go_.�� x64/src/net -trimpath ux_amd64/vet -I /tmp/go-build405-atomic -I ux_amd64/vet (dns block)
    • Triggering command: /tmp/go-build113590858/b001/ddevapp.test /tmp/go-build113590858/b001/ddevapp.test -test.testlogfile=/tmp/go-build113590858/b001/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true -test.run=TestAllocateAvailablePortForRouter _64-linux-gnu/13-ifaceassert ux_amd64/vet 1238638/b166/ s ead ux_amd64/vet -p f13/cobra/active-errorsas f13/cobra/args.g-ifaceassert ux_amd64/vet 1238638/b166/ 1238638/b166/ -I ux_amd64/vet (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@github-actions github-actions Bot added bugfix dependencies Pull requests that update a dependency file labels Jan 30, 2026
@github-actions

github-actions Bot commented Jan 30, 2026

Copy link
Copy Markdown

@rfay

rfay commented Jan 30, 2026

Copy link
Copy Markdown
Member

@copilot rewrite the OP in the format required by .github/PULL_REQUEST_TEMPLATE.md

Copilot AI commented Jan 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot rewrite the OP in the format required by .github/PULL_REQUEST_TEMPLATE.md

The Issue

When all DDEV projects are stopped, the router displays: "WARNING: No config files found or no routers expected". This is a valid healthy state that should not generate warnings.

How This PR Solves The Issue

1. Fixed healthcheck logic (traefik_healthcheck.sh):

  • Modified to treat expected_router_count == 0 with error_count == 0 as healthy
  • Previous logic required expected_router_count > 0, causing the zero-router state to trigger warnings
  • Removed misleading "No config files found" warning message

2. Added proactive healthcheck clearing (router.go, stop.go):

  • Created ClearRouterHealthcheck() function to force immediate healthcheck execution
  • Refactored StartDdevRouter() to use the new reusable function
  • Call ClearRouterHealthcheck() after ddev stop completes

This ensures router status updates immediately when projects stop, rather than waiting up to 59 seconds for the next periodic healthcheck cycle.

Manual Testing Instructions

  1. Start two DDEV projects: ddev start in each project directory
  2. Run ddev list - verify router shows "OK" status at ~/.ddev
  3. Stop both projects: ddev stop in each directory
  4. Run ddev list immediately - verify router shows "OK" status at ~/.ddev WITHOUT the warning message
  5. Repeat with variations:
    • Stop all projects, start one, stop it, run ddev list
    • Expected: Router always shows "OK" without warnings when all projects are stopped

Automated Testing Overview

Changes are to shell script healthcheck logic and Go code for router management. Testing requires:

  • Router container with updated healthcheck script (requires new image build)
  • Integration tests would need Docker environment with projects starting/stopping

The healthcheck shell script was validated with shellcheck. Go code builds successfully and follows existing patterns in the codebase.

Release/Deployment Notes

  • Requires new ddev-traefik-router container image to be built and published with updated healthcheck script
  • No breaking changes - purely fixes incorrect warning behavior
  • Users will see improved router status reporting when all projects are stopped

@rfay

rfay commented Jan 31, 2026

Copy link
Copy Markdown
Member

I don't think we should finish review or pull this until after the release, because we already have pretty good miles on the router as it is, and fiddling with it is not a great idea, especially for something that we can't easily reproduce and that does no harm anyway.

@rpkoller

Copy link
Copy Markdown
Collaborator

this would be a good candidate for targeting in 1.25.1. the current state of HEAD is good to go for 1.25.0 imho.

Copilot AI and others added 5 commits February 3, 2026 09:21
When all DDEV projects are stopped, the router healthcheck was incorrectly
showing a warning "No config files found or no routers expected". This is
actually a valid healthy state.

Changes:
- Modified traefik_healthcheck.sh to treat expected_router_count == 0 as
  a healthy state when there are no errors
- Removed the misleading warning message about no config files
- Updated health check logic to properly handle the "all projects stopped" case

The router will now show "OK" status with location "~/.ddev" without any
warnings when all projects are stopped.

Co-authored-by: rfay <112444+rfay@users.noreply.github.com>
- Created new ClearRouterHealthcheck() function to force immediate healthcheck
- Refactored StartDdevRouter() to use the new function
- Added call to ClearRouterHealthcheck() after ddev stop completes

This ensures the router status is updated immediately when projects are
stopped, providing users with accurate status information without waiting
for the next periodic healthcheck cycle.

Co-authored-by: rfay <112444+rfay@users.noreply.github.com>
@rfay rfay force-pushed the copilot/fix-router-status-issue branch from d2b2f7f to be0b38d Compare February 3, 2026 16:54
@rfay rfay force-pushed the copilot/fix-router-status-issue branch from be0b38d to 7229ae9 Compare February 3, 2026 17:00
@rfay rfay marked this pull request as ready for review February 3, 2026 17:00
@rfay rfay requested a review from a team as a code owner February 3, 2026 17:00

@rfay rfay 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.

The router healthcheck had an insistence that the router count be greater than zero, which doesn't make sense now that we leave the router running when there are no projects. This cleans that up and does a bit of rechecking along the way.

This looks good to me. I updated a couple of variable names for clarity and tried to improve comments.

@rfay rfay requested a review from stasadev February 3, 2026 17:01
@stasadev stasadev changed the title fix: router healthcheck incorrectly warns when all projects stopped fix: router healthcheck incorrectly warns when all projects stopped, fixes #8081 Feb 3, 2026

@stasadev stasadev 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.

Looks good to me, I confirm seeing a warning on v1.25.0, and this PR doesn't have it.

I used this command for testing:

ddev list --continuous

@rfay

rfay commented Feb 3, 2026

Copy link
Copy Markdown
Member

Brilliant, ddev list --continuous !

@rfay rfay merged commit b33af3a into main Feb 4, 2026
53 checks passed
@rfay rfay deleted the copilot/fix-router-status-issue branch February 4, 2026 19:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stopping all projects can lead into a "no config files found or no routers expected" warning

4 participants