{"record":{"id":"89982c827189f16e","repo":"xpipe-io/xpipe","slug":"unknown-principal-pr","errorCode":null,"errorMessage":"Unknown principal \" + pr","messagePattern":"Unknown principal \" \\+ pr","errorType":"exception","errorClass":"BeaconClientException","httpStatus":400,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/beacon/api/SecretEncryptExchange.java","lineNumber":52,"sourceCode":"            for (String pr : msg.getPrincipals()) {\n                var byName = DataStorageAccessHandler.getInstance().getAllEncryptionPrincipals().stream()\n                        .filter(encryptionPrincipal ->\n                                encryptionPrincipal.getName().equals(pr))\n                        .findFirst();\n                if (byName.isPresent()) {\n                    p = byName.get();\n                } else {\n                    var uuid = UuidHelper.parse(pr);\n                    if (uuid.isPresent()) {\n                        var principal = DataStorageAccessHandler.getInstance().getEncryptionPrincipal(uuid.get());\n                        p = principal.orElse(null);\n                    } else {\n                        p = null;\n                    }\n                }\n\n                if (p == null) {\n                    throw new BeaconClientException(\"Unknown principal \" + pr);\n                }\n\n                if (!p.isAccessible()) {\n                    throw new BeaconClientException(\"Principal \" + p.getName() + \" is not accessible\");\n                }\n\n                resolvedPrincipals.add(p);\n            }\n        }\n\n        if (resolvedPrincipals.isEmpty()) {\n            resolvedPrincipals.add(DataStorageAccessHandler.getInstance().getEncryptAllPrincipal());\n        }\n\n        var secret = MultiPrincipalSecret.of(InPlaceSecretValue.of(msg.getValue()), resolvedPrincipals);\n        return Response.builder().encrypted(secret.serialize()).build();\n    }\n","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/beacon/api/SecretEncryptExchange.java#L34-L70","documentation":"SecretEncryptExchange resolves each requested principal (user/system account) by name or id. When a principal string from msg cannot be resolved to a known principal on this system, the daemon throws 'Unknown principal <pr>'. Encryption must be bound to real principals so the resulting secret can later be decrypted for them.","triggerScenarios":"Calling the encrypt endpoint with a principal entry (username/UUID) that doesn't exist on the daemon's host — renamed user, deleted account, wrong identifier format, or requesting encryption for a user on the wrong target machine.","commonSituations":"Hardcoded usernames that differ between dev and prod hosts; users renamed or removed after secrets were first provisioned; passing a display name where a UUID (or vice versa) is required; scripts running against a different host than intended.","solutions":["List the available principals on the target host and use an exact matching name/id","Fix typos or update the username after account renames","Verify you are calling the daemon on the machine where the principal exists","Pass the identifier in the format the API expects (UUID vs name)"],"exampleFix":"// before\nrequest.setPrincipals(List.of(\"svc-app\"));\n// after\nList<String> known = client.listPrincipals();\nif (!known.contains(\"svc-app\")) {\n    throw new IllegalArgumentException(\"svc-app not on this host; known: \" + known);\n}\nrequest.setPrincipals(List.of(\"svc-app\"));","handlingStrategy":"validation","validationCode":"List<String> known = client.listPrincipals();\nfor (String pr : requested) {\n    if (!known.contains(pr)) {\n        throw new IllegalArgumentException(\"Unknown principal: \" + pr + \"; known: \" + known);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    client.encryptSecret(request);\n} catch (BeaconClientException e) {\n    if (e.getMessage().startsWith(\"Unknown principal\")) {\n        logger.warn(\"Principal missing on host, dropping it: \" + e.getMessage());\n        request.setPrincipals(request.getPrincipals().stream()\n            .filter(p -> !e.getMessage().endsWith(p)).toList());\n    } else throw e;\n}","preventionTips":["Resolve principal names/ids from a live listing, not hardcoded values","Use the identifier format the API expects (name vs UUID)","Confirm the target host actually has the account","Update scripts after user renames/deletions"],"tags":["beacon-api","secrets","principals"],"backgroundTag":"user-not-found","analyzedSha":"d85ca821baa46092a320ebb13546d7240adb74f8","analyzedAt":"2026-09-06T14:30:08.251Z","contentChangedAt":"2026-09-06T14:30:08.251Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}