xpipe-io/xpipe · error · ValidationException
Key file is not synced
Error message
Key file is not synced
What it means
SyncedIdentityStore.checkComplete() validates SSH identity stores. When the identity strategy is a key file, the file must live inside XPipe's data directory so it can be synced/backed up with the store. A key file stored outside the data directory cannot be synchronized, so validation fails with ValidationException("Key file is not synced").
Source
Thrown at ext/base/src/main/java/io/xpipe/ext/base/identity/SyncedIdentityStore.java:107
return password != null ? password.getValue() : null;
}
@Override
public SshIdentityStrategy getSshIdentity() {
return sshIdentity != null ? sshIdentity.getValue() : null;
}
@Override
public List<DataStoreEntryRef<?>> getDependencies() {
return List.of();
}
@Override
public void checkComplete() throws ValidationException {
super.checkComplete();
if (getSshIdentity() instanceof KeyFileStrategy f) {
if (!f.getFile().isInDataDirectory()) {
throw new ValidationException("Key file is not synced");
}
}
}
OptionalEncryptedValue<SecretRetrievalStrategy> getEncryptedPassword() {
return password;
}
OptionalEncryptedValue<SshIdentityStrategy> getEncryptedSshIdentity() {
return sshIdentity;
}
@Override
public DataStore withUpdatedPrincipals() {
var targetScope = DataStoreAccessScope.getTargetScope(accessScope);
if (targetScope != null && targetScope.equals(DataStoreAccessScope.vault())) {
targetScope = null;
}View on GitHub (pinned to d85ca821ba)
Solutions
- Copy or import the key file into the XPipe data directory and point the identity store at the synced copy
- Use XPipe's key-file import UI which automatically copies the key into the data directory instead of referencing the external path
- Choose a different identity strategy (e.g. agent-based) that does not require a synced key file
- If the key legitimately lives elsewhere, run the store without requiring sync/validation of this field
Example fix
// before
var identity = new SyncedIdentityStore(
new KeyFileStrategy(FilePath.of("~/.ssh/id_rsa")), null, null);
// after
var syncedKey = FilePath.of(DataStorage.get().installPath(true))
.join("id_rsa"); // copy key file here first
var identity = new SyncedIdentityStore(
new KeyFileStrategy(syncedKey), null, null); Defensive patterns
Strategy: validation
Validate before calling
if (identity.getSshIdentity() instanceof KeyFileStrategy f
&& !f.getFile().isInDataDirectory()) {
// fix or copy the key into the data directory before checkComplete()
} Type guard
boolean isSynced(SecretRetrievalStrategy s) {
return !(s instanceof KeyFileStrategy f) || f.getFile().isInDataDirectory();
} Try / catch
try { store.checkComplete(); }
catch (ValidationException e) {
if ("Key file is not synced".equals(e.getMessage())) { /* prompt key import */ }
} Prevention
- Always import key files through XPipe's UI so they are copied into the data directory
- Never point identity stores at raw ~/.ssh paths when sync is required
When it happens
Trigger: Calling checkComplete() (directly or via store save/validation) on a SyncedIdentityStore whose getSshIdentity() is a KeyFileStrategy whose getFile().isInDataDirectory() returns false — i.e. the key file path points outside the XPipe data directory.
Common situations: Users select a private key from ~/.ssh/ or another home location instead of importing/copying it into the XPipe-managed data directory; identity stores copied from another machine referencing absolute external paths; key files moved or deleted from the data directory.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Identity access scope is not currently accessible
- Cannot delete category: " + cat.getName()
- Not a toggleable connection
- Directory is a root
- Principal ${name} is not accessible
AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06).
Data as JSON: /api/errors/1b39e1290821194c.
Report an issue: GitHub.