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

  1. Copy or import the key file into the XPipe data directory and point the identity store at the synced copy
  2. Use XPipe's key-file import UI which automatically copies the key into the data directory instead of referencing the external path
  3. Choose a different identity strategy (e.g. agent-based) that does not require a synced key file
  4. 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

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


AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06). Data as JSON: /api/errors/1b39e1290821194c. Report an issue: GitHub.