zhisheng17/flink-learning · error · IOException

Failed to deserialize state handle from ConfigMap data {}.

Error message

Failed to deserialize state handle from ConfigMap data {}.

What it means

deserializeObject() wraps IOException/ClassNotFoundException from InstantiationUtil.deserializeObject of the Base64-decoded ConfigMap value into this IOException. The stored state handle bytes cannot be turned back into an object, usually due to an incompatible classpath.

Source

Thrown at flink-learning-k8s/flink-k8s/src/main/java/org/apache/flink/kubernetes/highavailability/KubernetesStateHandleStore.java:425

	@Override
	public void releaseAll() {
		// noop
	}

	@Override
	public String toString() {
		return this.getClass().getSimpleName() + "{configMapName='" + configMapName + "'}";
	}

	private RetrievableStateHandle<T> deserializeObject(String content) throws IOException {
		checkNotNull(content, "Content should not be null.");

		final byte[] data = Base64.getDecoder().decode(content);

		try {
			return InstantiationUtil.deserializeObject(data, Thread.currentThread().getContextClassLoader());
		} catch (IOException | ClassNotFoundException e) {
			throw new IOException("Failed to deserialize state handle from ConfigMap data " +
				content + '.', e);
		}
	}

	private KubernetesException getConfigMapNotExistException() {
		return new KubernetesException("ConfigMap " + configMapName + " does not exists. " +
			"It may be deleted externally.");
	}

	private NotExistException getKeyNotExistException(String key) {
		return new NotExistException("Could not find " + key + " in ConfigMap " + configMapName);
	}

	private AlreadyExistException getKeyAlreadyExistException(String key) {
		return new AlreadyExistException(key + " already exists in ConfigMap " + configMapName);
	}

	private String encodeStateHandle(byte[] serializedStoreHandle) {

View on GitHub (pinned to d731cee761)

Solutions

  1. Align the reader's classpath/Flink version with the writer that stored the state handle.
  2. Ensure user-code classes are on the classpath (or in the job jar) of the recovering process — check Thread.currentThread().getContextClassLoader().
  3. If the data is stale/incompatible, delete the offending ConfigMap key and let the job re-register its state.
  4. Verify the ConfigMap value was not hand-edited; re-write it via the API instead.

Example fix

// before: recovery fails with ClassNotFoundException for user classes
kubectl get cm flink-ha -o yaml  # job-xxx payload from old jar
// after: remove stale handle so the job re-registers
kubectl delete key: kubectl patch cm flink-ha --type json -p '[{"op":"remove","path":"/data/job-xxx"}]'
Defensive patterns

Strategy: validation

Validate before calling

// verify the stored payload decodes and its classes resolve before recovery use
byte[] data = Base64.getDecoder().decode(content);
Class.forName(stateHandleClassName, false, Thread.currentThread().getContextClassLoader());

Try / catch

try {
    StoredStateHandle h = store.getAndLock(key, lockIdentity);
} catch (IOException e) {
    if (ExceptionUtils.findThrowable(e, ClassNotFoundException.class).isPresent()) {
        // stale/incompatible handle: purge key and re-register
    }
}

Prevention

When it happens

Trigger: getAndLock, getAllAndLock, releaseAndTryRemove, or releaseAndTryRemoveAll reading a ConfigMap entry whose payload was written by a different Flink/job version whose classes are missing or moved (ClassNotFoundException), or the Base64 payload is corrupted/truncated.

Common situations: Upgrading Flink or the job jar without draining old HA state; user-code classes present at write time but absent on the recovery classpath (no userCodeLoader); manual edits to ConfigMap data breaking Base64.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of zhisheng17/flink-learning@d731cee761 (2026-09-06). Data as JSON: /api/errors/40963249f7d1a2e5. Report an issue: GitHub.