Traefik
Cert-Manager
HTTP-01 Challenge
Kubernetes
TLS Certificates

Skipping service no endpoints found when attempting to fetch certificate with traefik 2 cert-manager http-01 challenge

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When Traefik logs "Skipping service: no endpoints found" during a cert-manager HTTP-01 flow, the message usually means the temporary ACME solver service exists but does not currently point at any ready pod. The certificate request is failing because the challenge path cannot be served, not because Let's Encrypt is rejecting you for an unrelated reason. The fix is usually in one of three places: solver pod readiness, ingress class wiring, or Traefik watching the wrong resource type.

What Happens During an HTTP-01 Challenge

For an HTTP-01 challenge, cert-manager creates temporary Kubernetes objects to answer requests under /.well-known/acme-challenge/.... In a common setup, that includes:

  • a temporary solver pod
  • a temporary service pointing at that pod
  • a temporary Ingress object that routes the challenge path

Traefik must watch that Ingress, discover the temporary service, and see a ready endpoint behind it. If any one of those steps fails, Traefik may report that the service has no endpoints.

Start With the Temporary Solver Resources

The fastest diagnostic loop is to inspect the resources cert-manager created:

bash
kubectl get certificate,order,challenge -A
kubectl get ingress,svc,endpoints,pods -A | grep cm-acme-http-solver
kubectl describe challenge -n my-namespace my-cert-1234567890

What you want to see is:

  • a solver pod in Running state
  • a service named like cm-acme-http-solver-*
  • an endpoints object containing the solver pod IP

If the service exists but the endpoints object is empty, Traefik's message is accurate. The problem is upstream of Traefik routing.

Make Sure cert-manager Uses the Traefik Ingress Class

A very common issue is that cert-manager creates a temporary Ingress, but it uses the wrong class or no class at all. Then Traefik ignores it.

A clean ClusterIssuer for Traefik-backed HTTP-01 looks like this:

yaml
1apiVersion: cert-manager.io/v1
2kind: ClusterIssuer
3metadata:
4  name: letsencrypt-staging
5spec:
6  acme:
7    email: [email protected]
8    server: https://acme-staging-v02.api.letsencrypt.org/directory
9    privateKeySecretRef:
10      name: letsencrypt-staging-account-key
11    solvers:
12      - http01:
13          ingress:
14            ingressClassName: traefik

On newer cert-manager releases, ingressClassName is the clearer option. The important point is that the solver Ingress must be claimed by the same Traefik instance that serves public HTTP traffic.

Your application Ingress should align with that class as well:

yaml
1apiVersion: networking.k8s.io/v1
2kind: Ingress
3metadata:
4  name: app
5  annotations:
6    cert-manager.io/cluster-issuer: letsencrypt-staging
7spec:
8  ingressClassName: traefik
9  rules:
10    - host: app.example.com
11      http:
12        paths:
13          - path: /
14            pathType: Prefix
15            backend:
16              service:
17                name: app-service
18                port:
19                  number: 80
20  tls:
21    - hosts:
22        - app.example.com
23      secretName: app-tls

Traefik Must Watch Kubernetes Ingress Resources

Another subtle failure mode appears when teams use Traefik CRDs such as IngressRoute for their normal app traffic and disable the standard Kubernetes Ingress provider. cert-manager's default HTTP-01 solver creates a normal Ingress, not a Traefik IngressRoute.

If Traefik is only watching CRDs, the solver Ingress never becomes routable. The log message may still look like a missing-endpoints problem because the temporary service was created, but the real issue is that Traefik is not handling the solver route at all.

So confirm that your Traefik deployment is watching Kubernetes Ingress resources in addition to any CRD provider you use.

Check Why the Solver Pod Has No Endpoints

If the Ingress class is correct, inspect the pod itself:

bash
kubectl get pods -n my-namespace -l acme.cert-manager.io/http01-solver=true
kubectl describe pod -n my-namespace cm-acme-http-solver-abcde
kubectl logs -n my-namespace cm-acme-http-solver-abcde

Common causes of empty endpoints include:

  • the pod never scheduled because of resource pressure
  • a restrictive NetworkPolicy
  • a service selector mismatch
  • the pod is not ready yet

Because the solver resources are short-lived, timing matters. It is worth watching them live while the challenge runs.

External Reachability Still Matters

Even if the endpoints exist, Let's Encrypt still must reach the domain over plain HTTP on port 80. A correct in-cluster config can still fail if DNS points elsewhere, the load balancer is misrouted, or port 80 is blocked.

A quick check from outside the cluster is:

bash
curl -I http://app.example.com/.well-known/acme-challenge/test

You will not get a valid token at that fake path, but you should at least see that the request lands on the ingress layer instead of timing out or reaching the wrong system.

Common Pitfalls

The most common mistake is assuming the error is about the permanent application service. For HTTP-01, Traefik is usually complaining about the temporary cm-acme-http-solver-* service, not your main app backend.

Another mistake is mixing Traefik CRDs with cert-manager's default Ingress solver without making sure the standard Kubernetes Ingress provider is enabled.

Teams also often forget to set the solver ingress class. If cert-manager creates an unclassified Ingress, the wrong controller may claim it, or no controller may claim it at all.

Finally, do not debug against the production Let's Encrypt endpoint first. Use the staging issuer until the routing flow is stable, otherwise you burn through rate limits while fixing cluster wiring.

Summary

  • "No endpoints found" usually means the temporary ACME solver service has no ready pod behind it.
  • Check Challenge, solver pod, service, and endpoints objects together.
  • Make sure cert-manager creates the solver Ingress with the Traefik ingress class.
  • If you use Traefik IngressRoute, also ensure Traefik watches normal Kubernetes Ingress resources.
  • Verify external DNS and port 80 reachability after the in-cluster pieces look correct.

Course illustration
Course illustration

All Rights Reserved.