{"record":{"id":"6f8f19683c39492a","repo":"juanfont/headscale","slug":"writing-tls-key-to-container-w-6f8f19","errorCode":null,"errorMessage":"writing TLS key to container: %w","messagePattern":"writing TLS key to container: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"integration/hsic/hsic.go","lineNumber":620,"sourceCode":"\t\treturn nil, fmt.Errorf(\"writing headscale config to container: %w\", err)\n\t}\n\n\tif hsic.aclPolicy != nil {\n\t\terr = hsic.writePolicy(hsic.aclPolicy)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"writing policy: %w\", err)\n\t\t}\n\t}\n\n\tif hsic.hasTLS() {\n\t\terr = hsic.WriteFile(tlsCertPath, hsic.tlsCert)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"writing TLS certificate to container: %w\", err)\n\t\t}\n\n\t\terr = hsic.WriteFile(tlsKeyPath, hsic.tlsKey)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"writing TLS key to container: %w\", err)\n\t\t}\n\t}\n\n\tfor _, f := range hsic.filesInContainer {\n\t\terr := hsic.WriteFile(f.path, f.contents)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"writing %q: %w\", f.path, err)\n\t\t}\n\t}\n\n\t// Load the database from policy file on repeat until it succeeds,\n\t// this is done as the container sleeps before starting headscale.\n\tif hsic.aclPolicy != nil && hsic.policyMode == types.PolicyModeDB {\n\t\terr := pool.Retry(hsic.reloadDatabasePolicy)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"loading database policy on startup: %w\", err)\n\t\t}\n\t}","sourceCodeStart":602,"sourceCodeEnd":638,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/integration/hsic/hsic.go#L602-L638","documentation":"Companion to 676: writing the TLS private key to tlsKeyPath failed. Same mechanism (docker file write into the container), same failure modes; only the artifact (key PEM) differs.","triggerScenarios":"hasTLS() true and hsic.WriteFile(tlsKeyPath, hsic.tlsKey) fails after the cert write succeeded — partial TLS setup: cert written, key not, leaving the container misconfigured if the error were ignored (it is not; construction aborts).","commonSituations":"Container dying between the two writes under memory pressure; transient exec failure; custom image lacking the key path.","solutions":["Check container status and logs — it died between cert and key write","Free Docker resources (memory/CPU pressure causes mid-setup container deaths)","Verify tlsKeyPath exists/writable in the image","Re-run the scenario after cleanup"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if !pemValid(hsic.tlsKey) { return nil, fmt.Errorf(\"tls key not valid PEM\") }","typeGuard":"func pemPrivateKey(b []byte) bool {\n    blk, _ := pem.Decode(b)\n    return blk != nil && strings.Contains(blk.Type, \"PRIVATE KEY\")\n}","tryCatchPattern":null,"preventionTips":["Supply a matching cert/key pair from one generation run","Watch for containers dying between cert and key writes under memory pressure","Free Docker resources when mid-setup deaths become frequent"],"tags":["integration-test","tls","docker","file-copy"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}