Skip to content

[Bug]: Error no certs found when trying to add the caBundle to the client cert pool due to certificate tags not in the certificate text(bundle) #1497

@bradmesserle

Description

@bradmesserle

Also dont know if this in the correct project.. we might need to move this bug ticket..

Steps to Reproduce

On mac or linux run step ca init.

  1. get the root pem file.
  2. https://go.dev/play/p/Di8eQE7Or17 and put the pem file into this golang playground and hit go..

Updates to the bug. I understand what is going on..

If you only put the root cert in the caBundle section, when the client tries to append the cert to the pool it will fail because it is not wrapped in -----BEGIN CERTIFICATE----- -----END CERTIFICATE-----

This is why i think i am getting no certificate errors.

I am new to all of this smallstep / kubernetes / go.. but i am going to try to do a code a fix. I sort of don't know how i am just now finding this, unless i am doing something wrong.

So i forked the issuer project and iss.Spec.CABundle is actually the cert and not the PEM text.. soo. i dont know where when you apply the yaml file it gets converted to the actual cert binary.. but on the issuer side we need to convert it back over the PEM format in order for the below client code to work.

So the issue is the issuer is not sending down PEM data it is sending down the actual cert. Need to check if there is a different api on the client to call then getTransportFromCABundle api that takes the cert bytes..

this is where it failing..

smallstep go client.go
func getTransportFromCABundle(bundle []byte) (http.RoundTripper, error) {
pool := x509.NewCertPool()
if !pool.AppendCertsFromPEM(bundle) {
return nil, errors.New("error parsing ca bundle: no certificates found")
}
return getDefaultTransport(&tls.Config{
MinVersion: tls.VersionTLS12,
PreferServerCipherSuites: true,
RootCAs: pool,
}), nil
}

func (r *StepClusterIssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)
so in this function maybe we create a config map for the root.ca? like issuer-ca and when we create the config map wrap the cert with the tags if they are not present.. and then update the code to just use the config map? and so some validation checks before it get down to the client code? also would like to make the error text a little more descriptive so we know what is going on from the start.. :)

issues yaml file..

`
apiVersion: certmanager.step.sm/v1beta1
kind: StepClusterIssuer
metadata:
name: step-cluster-issuer
namespace: default
spec:
url: https://k3s-devops-01
caBundle: MIIB3zCCAYWgAwIBAgIQKYv9Uhi4ml9d3ZDRYfIG2TAKBggqhkjOPQQDAjBOMSEwHwYDVQQKExhkZXZvcHMuYWlkZXZlbG9wbWVudC5sYWIxKTAnBgNVBAMTIGRldm9wcy5haWRldmVsb3BtZW50LmxhYiBSb290IENBMB4XDTI1MTAxMTEyMzIwM1oXDTM1MTAwOTEyMzIwM1owTjEhMB8GA1UEChMYZGV2b3BzLmFpZGV2ZWxvcG1lbnQubGFiMSkwJwYDVQQDEyBkZXZvcHMuYWlkZXZlbG9wbWVudC5sYWIgUm9vdCBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABIu9d2Ib3TDHBKDL63lO+cyIBOV+dv+TRpj5l0qXwVqNW5U1kIhNOMTz4mrQgJtgaSKBWER15NsabJ1QqrpuvrmjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBSu7ZlS115iy35GGQuTQrsQJg4/tjAKBggqhkjOPQQDAgNIADBFAiBFs3jbaFZuwEgl/vdUsPJ5vQfWyvhsG4zfGKGiHXVuFwIhAJdpLrmZdh6UCQx/ypQ7y2h0xYjYQBh5TqMl0FgsD1dw

provisioner:
name: ca-master
kid: srvjUgeOrh1PLJ6cHcLX4PgahJkrpnFHVbDFiH83NH4
passwordRef:
name: step-certificates-ca-password
key: password
namespace: default

`

Here is the error..

{"level":"error","ts":"2025-10-11T22:36:30-04:00","msg":"Reconciler error","controller":"stepclusterissuer","controllerGroup":"certmanager.step.sm","controllerKind":"StepClusterIssuer","StepClusterIssuer":{"name":"step-cluster-issuer"},"namespace":"","name":"step-cluster-issuer","reconcileID":"1de14a9e-c9b2-4f30-92ca-dbcb667c12be","error":"error parsing ca bundle: no certificates found","errorVerbose":"error parsing ca bundle: no certificates found\ngithub.com/smallstep/certificates/ca.getTransportFromCABundle\n\t/Users/bradleymesserle/go/pkg/mod/github.com/smallstep/certificates@v0.28.4/ca/client.go:442\ngithub.com/smallstep/certificates/ca.(*clientOptions).getTransport\n\t/Users/bradleymesserle/go/pkg/mod/github.com/smallstep/certificates@v0.28.4/ca/client.go:226\ngithub.com/smallstep/certificates/ca.NewClient\n\t/Users/bradleymesserle/go/pkg/mod/github.com/smallstep/certificates@v0.28.4/ca/client.go:580\ngithub.com/smallstep/certificates/ca.NewProvisioner\n\t/Users/bradleymesserle/go/pkg/mod/github.com/smallstep/certificates@v0.28.4/ca/provisioner.go:38\ngithub.com/smallstep/step-issuer/provisioners.NewFromStepClusterIssuer\n\t/Users/bradleymesserle/Downloads/smallstep-issuer/provisioners/step.go:54\ngithub.com/smallstep/step-issuer/controllers.(*StepClusterIssuerReconciler).Reconcile\n\t/Users/bradleymesserle/Downloads/smallstep-issuer/controllers/stepclusterissuer_controller.go:90\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller[...]).Reconcile\n\t/Users/bradleymesserle/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.22.1/pkg/internal/controller/controller.go:216\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller[...]).reconcileHandler\n\t/Users/bradleymesserle/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.22.1/pkg/internal/controller/controller.go:461\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller[...]).processNextWorkItem\n\t/Users/bradleymesserle/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.22.1/pkg/internal/controller/controller.go:421\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller[...]).Start.func1.1\n\t/Users/bradleymesserle/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.22.1/pkg/internal/controller/controller.go:296\nruntime.goexit\n\t/Users/bradleymesserle/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.0.darwin-amd64/src/runtime/asm_amd64.s:1700","stacktrace":"sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller[...]).reconcileHandler\n\t/Users/bradleymesserle/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.22.1/pkg/internal/controller/controller.go:474\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller[...]).processNextWorkItem\n\t/Users/bradleymesserle/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.22.1/pkg/internal/controller/controller.go:421\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller[...]).Start.func1.1\n\t/Users/bradleymesserle/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.22.1/pkg/internal/controller/controller.go:296"}

I have debugged this to finally figure out the root cert go cant handle. But i can import the root ca in my macos keychain no problem. and open ssl can read it as well..

Certificate:
Data:
Version: 3 (0x2)
Serial Number:
29:8b:fd:52:18:b8:9a:5f:5d:dd:90:d1:61:f2:06:d9
Signature Algorithm: ecdsa-with-SHA256
Issuer: O = devops.aidevelopment.lab, CN = devops.aidevelopment.lab Root CA
Validity
Not Before: Oct 11 12:32:03 2025 GMT
Not After : Oct 9 12:32:03 2035 GMT
Subject: O = devops.aidevelopment.lab, CN = devops.aidevelopment.lab Root CA
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:8b:bd:77:62:1b:dd:30:c7:04:a0:cb:eb:79:4e:
f9:cc:88:04:e5:7e:76:ff:93:46:98:f9:97:4a:97:
c1:5a:8d:5b:95:35:90:88:4d:38:c4:f3:e2:6a:d0:
80:9b:60:69:22:81:58:44:75:e4:db:1a:6c:9d:50:
aa:ba:6e:be:b9
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:1
X509v3 Subject Key Identifier:
AE:ED:99:52:D7:5E:62:CB:7E:46:19:0B:93:42:BB:10:26:0E:3F:B6
Signature Algorithm: ecdsa-with-SHA256
30:45:02:20:45:b3:78:db:68:56:6e:c0:48:25:fe:f7:54:b0:
f2:79:bd:07:d6:ca:f8:6c:1b:8c:df:18:a1:a2:1d:75:6e:17:
02:21:00:97:69:2e:b9:99:76:1e:94:09:0c:7f:ca:94:3b:cb:
68:74:c5:88:d8:40:18:79:4e:a3:25:d0:58:2c:0f:57:70

but no go with go.. :(

Your Environment

  • OS - mac and linux
  • step CLI Version -
  • Smallstep CLI/0.28.7 (linux/arm64)
    Release Date: 2025-07-14T04:10:42Z

Expected Behavior

Go to be able to read the root cert

Actual Behavior

The isssuer crd has caBundle field. and if the the cert is not wrapped with begin cert and end cert tags the cert will not get added to the pool and will throw an error no cert found. thus failing to connect to the ca.

Additional Context

No response

Contributing

Vote on this issue by adding a 👍 reaction.
To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugneeds triageWaiting for discussion / prioritization by team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions