Skip to content

ns8-metrics: false certificate alerts from stale Traefik metrics #8191

Closed

Description

@stephdl

Steps to reproduce

  • Have a node certificate covering several names, e.g. posta.example.com, node3.example.net, proxy3.example.net
  • Let it be reissued with a different CN but the same name set, here posta.example.com to node3.example.net
  • Do not restart Traefik
  • Wait until the old certificate has less than 28 days left

Expected behavior

No alert. The only certificate in acme.json is valid for about 90 more days, and the TLS certificates page shows it as valid.

Actual behavior

CertExpiringSoon fires, then CertExpiringCritical, then CertExpired, which never clears.

Traefik keeps exposing traefik_tls_certs_not_after for a certificate it has replaced, until it restarts. Upstream: traefik/traefik#8606.

rules.d/tlscert.yml aggregates with max by (cn, sans), which masks a stale series only while CN and SANs both stay the same. On a CN change the stale series forms its own group and alerts alone.

Seen on a production cluster, two nodes:

2026-10-15  traefik4  posta.example.com  node3.example.net,posta.example.com,proxy3.example.net  511458900122312166490624809264886668471982
2026-12-14  traefik4  node3.example.net  node3.example.net,posta.example.com,proxy3.example.net  519048561576165143401225526064484491625112

Serial …471982 is gone from acme.json, per api-cli run module/traefik4/list-certificates. Same on traefik8, CN moved from proxy6.example.net to node6.example.net. About twenty other stale series sit on those nodes, silent only because their CN did not change.

Same expression drops the node and module_id labels. Annotations read "TLS certificate on Node expires in …", and alert-proxy builds cert-expiring-soon:<cn>:node:unknown.

Workaround

Restart the Traefik instance, the alert clears after the 5m for window.

runagent -m traefik4 systemctl --user restart traefik

It drops HTTPS for a few seconds, so not an option on shared production nodes, and it comes back on the next CN change.

Possible fixes

Short term, aggregate as max by (node, module_id, sans). Both stale series carry the same sans string as their replacement, so they get masked, and the labels come back. No restart needed. Still breaks if the name set changes, or if a certificate is deleted with no replacement.

Longer term, source the expiry from acme.json instead of the Traefik gauge. ns8-traefik already parses it in cert_helpers.list_internal_certificates, and certificate-exporter.path already fires on every change.

Components

  • ns8-metrics
  • ns8-traefik

See also

see mattermost talk https://mattermost.nethesis.it/nethesis/pl/xyaw4zw1d38jfcq7at4ijdei5r

Activity

  1. added and removed on Sep 29, 2026
  2. self-assigned this
    on Sep 30, 2026
  3. added theissue type on Sep 30, 2026
  4. DavidePrincipi commented on Oct 8, 2026

    @DavidePrincipi
    Member

    In Testing metrics 1.5.1-dev.2

    Test case 1

    • Update the module, then upload a custom certificate expiring in 15 days
    • Delete it and upload one with the same names but a different main name
    • Check Prometheus shows one ns8:traefik_tls_cert_not_after series for these names, with the node label, and no CertExpiringSoon alert for the old certificate
  5. 1 remaining item

  6. stephdl commented on Oct 13, 2026

    @stephdl
    Author

    In testing core 3.23.1-dev.4 and traefik 4.2.5-dev.1

    Test case 2

    • Upload a custom certificate
    • Delete it from the TLS certificates page. The modal shows the "Traefik will be restarted" warning
    • Check Traefik restarted: runagent -m traefik1 systemctl --user status traefik

    Test case 3

    • Delete a Let's Encrypt certificate. The modal still shows the warning
  7. stephdl commented on Oct 13, 2026

    @stephdl
    Author

    back to testing @DavidePrincipi

  8. DavidePrincipi commented on Oct 13, 2026

    @DavidePrincipi
    Member

    VERIFIED

  9. removed their assignment
    on Oct 13, 2026
  10. removed
    testingPackages are available from testing repositories
    on Oct 13, 2026
  11. moved this from Testing to Verified in NethServeron Oct 13, 2026
  12. DavidePrincipi commented on Oct 15, 2026

    @DavidePrincipi
    Member
  13. DavidePrincipi commented on Oct 15, 2026

    @DavidePrincipi
    Member
  14. moved this from Verified to Done in NethServeron Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    verifiedAll test cases were verified successfully

    Type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions