{"record":{"id":"1a1357567bbf1afd","repo":"halo-dev/halo","slug":"public-key-location-does-not-exist","errorCode":null,"errorMessage":"Public key location does not exist","messagePattern":"Public key location does not exist","errorType":"validation","errorClass":"InvalidConfigurationPropertyValueException","httpStatus":null,"severity":"critical","filePath":"application/src/main/java/run/halo/app/infra/properties/JwtProperties.java","lineNumber":106,"sourceCode":"    }\n\n    public void setPrivateKeyLocation(Resource privateKeyLocation) {\n        this.privateKeyLocation = privateKeyLocation;\n    }\n\n    public RSAPrivateKey getPrivateKey() {\n        return privateKey;\n    }\n\n    public RSAPublicKey getPublicKey() {\n        return publicKey;\n    }\n\n    private RSAPublicKey readPublicKey() throws IOException {\n        String key = \"halo.security.oauth2.jwt.public-key-location\";\n        Assert.notNull(this.publicKeyLocation, \"PublicKeyLocation must not be null\");\n        if (!this.publicKeyLocation.exists()) {\n            throw new InvalidConfigurationPropertyValueException(\n                    key, this.publicKeyLocation, \"Public key location does not exist\");\n        }\n        try (InputStream inputStream = this.publicKeyLocation.getInputStream()) {\n            String source = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);\n            return RsaKeyConverters.x509().convert(new ByteArrayInputStream(source.getBytes()));\n        }\n    }\n\n    private RSAPrivateKey readPrivateKey() throws IOException {\n        String key = \"halo.security.oauth2.jwt.private-key-location\";\n        Assert.notNull(this.privateKeyLocation, \"PrivateKeyLocation must not be null\");\n        if (!this.privateKeyLocation.exists()) {\n            throw new InvalidConfigurationPropertyValueException(\n                    key, this.privateKeyLocation, \"Private key location does not exist\");\n        }\n        try (InputStream inputStream = this.privateKeyLocation.getInputStream()) {\n            String source = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);\n            return RsaKeyConverters.pkcs8().convert(new ByteArrayInputStream(source.getBytes()));","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/application/src/main/java/run/halo/app/infra/properties/JwtProperties.java#L88-L124","documentation":"Thrown as Spring's InvalidConfigurationPropertyValueException from JwtProperties.readPublicKey during bean construction when halo.security.oauth2.jwt.public-key-location points at a Resource that reports exists()==false. Halo loads RSA keys at startup to sign/verify JWTs, so a missing public key resource is fatal to the security configuration.","triggerScenarios":"Application startup with the property set to a classpath/file/http resource that cannot be resolved (does not exist), e.g. a wrong path, a file not mounted in the container, or a classpath resource absent from the JAR.","commonSituations":"Docker/K8s deployment where the key volume isn't mounted; typo in the configured path; key file generated on a different node; moving config between environments without copying the key; default dev path pointing at a file that was git-ignored.","solutions":["Verify the resource path resolves: correct the halo.security.oauth2.jwt.public-key-location value.","Ensure the key file is present at the configured location in the runtime (mount the volume / copy into the image).","Use the classpath: prefix for bundled keys or file: for host-mounted keys, matching how the resource is shipped.","Confirm read permissions for the process user on the key file."],"exampleFix":"# before\nhalo.security.oauth2.jwt.public-key-location=classpath:jwt-public.pem\n# (file not packaged)\n\n# after\nhalo.security.oauth2.jwt.public-key-location=file:/etc/halo/keys/jwt-public.pem","handlingStrategy":"validation","validationCode":"Resource r = resourceLoader.getResource(publicKeyLocation);\nif (!r.exists()) {\n    throw new IllegalStateException(\"Public key resource missing: \" + publicKeyLocation);\n}","typeGuard":"static boolean resourceExists(Resource r) {\n    return r != null && r.exists();\n}","tryCatchPattern":"try {\n    new JwtProperties(issuer, algo, pubRes, privRes);\n} catch (InvalidConfigurationPropertyValueException e) {\n    // startup-blocking: log, point operator at the public-key-location property, abort boot\n    log.error(\"Configure halo.security.oauth2.jwt.public-key-location to an existing resource\", e);\n    throw e;\n}","preventionTips":["Smoke-test key resource existence in your deploy script before starting Halo.","Keep public/private key resources under version-controlled secrets management.","Use absolute paths or classpath: resources consistently across environments."],"tags":["security","jwt","configuration","startup","rsa-key"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}