{"record":{"id":"3aed5efd670fb5b3","repo":"slackhq/nebula","slug":"certificate-contained-an-unsafe-network-assignment","errorCode":null,"errorMessage":"certificate contained an unsafe network assignment outside the limitations of the signing ca: %s","messagePattern":"certificate contained an unsafe network assignment outside the limitations of the signing ca: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cert/ca_pool.go","lineNumber":339,"sourceCode":"\t\t\t\treturn fmt.Errorf(\"certificate contained a network assignment outside the limitations of the signing ca: %s\", certNetwork.String())\n\t\t\t}\n\t\t}\n\t}\n\n\t// If the signer has a limited set of subnet ranges to issue from make sure the cert only contains a subset\n\tsigningUnsafeNetworks := signer.UnsafeNetworks()\n\tif len(signingUnsafeNetworks) > 0 {\n\t\tfor _, certUnsafeNetwork := range unsafeNetworks {\n\t\t\tfound := false\n\t\t\tfor _, caNetwork := range signingUnsafeNetworks {\n\t\t\t\tif caNetwork.Contains(certUnsafeNetwork.Addr()) && caNetwork.Bits() <= certUnsafeNetwork.Bits() {\n\t\t\t\t\tfound = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !found {\n\t\t\t\treturn fmt.Errorf(\"certificate contained an unsafe network assignment outside the limitations of the signing ca: %s\", certUnsafeNetwork.String())\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":321,"sourceCodeEnd":346,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/cert/ca_pool.go#L321-L346","documentation":"If the signing CA restricts UnsafeNetworks (subnet routes it may advertise), each unsafe network prefix on the signed certificate must be contained within one of the CA's prefixes. This error names the cert's unsafe-network prefix that the CA is not permitted to issue.","triggerScenarios":"CheckCAConstraints(signer, sub) where a prefix in sub.UnsafeNetworks() is not covered by signer.UnsafeNetworks(); SignWith requesting an UnsafeNetworks entry outside the CA's limits; verify() after signature validation.","commonSituations":"Host advertises a routed subnet (e.g. 192.168.1.0/24) that the CA's allowlist doesn't cover; operator adds route advertisement to a host without updating the CA's UnsafeNetworks; prefix/bits misconfiguration where cert prefix is broader than any CA prefix.","solutions":["Remove the unsafe network from the cert, or narrow it to fit inside a CA-permitted prefix","Add the subnet to the signing CA's UnsafeNetworks list and re-issue the CA","Sign with a CA whose UnsafeNetworks cover the desired routes"],"exampleFix":"// before\nopts.UnsafeNetworks = []netip.Prefix{netip.MustParsePrefix(\"192.168.5.0/24\")} // not in CA\n// after\nopts.UnsafeNetworks = []netip.Prefix{netip.MustParsePrefix(\"192.168.1.0/24\")} // covered by CA","handlingStrategy":"validation","validationCode":"for _, n := range sub.UnsafeNetworks() {\n    covered := false\n    for _, ca := range signer.UnsafeNetworks() {\n        if ca.Contains(n.Addr()) && ca.Bits() <= n.Bits() {\n            covered = true\n            break\n        }\n    }\n    if !covered {\n        return fmt.Errorf(\"unsafe network %s outside CA limits\", n)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the CA's UnsafeNetworks allowlist in sync with routed subnets","Validate advertised routes against CA limits before signing","Never advertise prefixes broader than the CA permits","Document which CAs may originate which routes"],"tags":["certificate","unsafe-networks","routing","ca-constraints"],"backgroundTag":"certificate-constraint-violation","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}