apache/hadoop · error · IOException

No version in key path ${versionName}

Error message

No version in key path ${versionName}

What it means

getBaseName splits a version name such as '/aaa/bbb@3' into '/aaa/bbb' by cutting at the last '@'. If the string contains no '@' there is no version component to strip, so the method throws IOException rather than returning the input unchanged. A null input is rejected earlier with Objects.requireNonNull("VersionName cannot be null").

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java:647

  /**
   * Ensures that any changes to the keys are written to persistent store.
   * @throws IOException raised on errors performing I/O.
   */
  public abstract void flush() throws IOException;

  /**
   * Split the versionName in to a base name. Converts "/aaa/bbb@3" to
   * "/aaa/bbb".
   * @param versionName the version name to split
   * @return the base name of the key
   * @throws IOException raised on errors performing I/O.
   */
  public static String getBaseName(String versionName) throws IOException {
    Objects.requireNonNull(versionName, "VersionName cannot be null");
    int div = versionName.lastIndexOf('@');
    if (div == -1) {
      throw new IOException("No version in key path " + versionName);
    }
    return versionName.substring(0, div);
  }

  /**
   * Build a version string from a basename and version number. Converts
   * "/aaa/bbb" and 3 to "/aaa/bbb@3".
   * @param name the basename of the key
   * @param version the version of the key
   * @return the versionName of the key.
   */
  protected static String buildVersionName(String name, int version) {
    return name + "@" + version;
  }

  /**
   * Find the provider with the given key.
   *

View on GitHub (pinned to 2add963021)

Solutions

  1. Pass values obtained from KeyVersion.getVersionName() or buildVersionName(name, version)
  2. If the input may be a base name, check versionName.lastIndexOf('@') != -1 first and skip the split
  3. When constructing version names manually, always append '@' + version

Example fix

// before
String base = KeyProvider.getBaseName("/aaa/bbb"); // throws: no '@'

// after
String in = "/aaa/bbb";
int at = in.lastIndexOf('@');
String base = (at == -1) ? in : in.substring(0, at);
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean isVersionName(String s) {
  return s != null && s.lastIndexOf('@') != -1;
}

Type guard

static String baseNameOrSelf(String s) throws IOException {
  Objects.requireNonNull(s, "VersionName cannot be null");
  int at = s.lastIndexOf('@');
  return (at == -1) ? s : s.substring(0, at);
}

Try / catch

try { base = KeyProvider.getBaseName(versionName); } catch (IOException e) { if (String.valueOf(e.getMessage()).startsWith("No version in key path")) { base = versionName; /* input was already a base name */ } else { throw e; } }

Prevention

When it happens

Trigger: Passing a base key name ('/aaa/bbb') where a version name ('/aaa/bbb@0') is required; names assembled by string concatenation that dropped the '@version' suffix; parsing key names from external sources where the version tag was trimmed.

Common situations: Clients threading key base names into APIs that expect KeyVersion.getVersionName() values; log/config parsing that strips '@' segments as comments.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/6ccf97879c3877d3. Report an issue: GitHub.