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
- Align the reader's classpath/Flink version with the writer that stored the state handle.
- Ensure user-code classes are on the classpath (or in the job jar) of the recovering process — check Thread.currentThread().getContextClassLoader().
- If the data is stale/incompatible, delete the offending ConfigMap key and let the job re-register its state.
- 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
- Keep Flink and job-jar versions consistent between writer and recovery reader.
- Bundle user-code classes in the recovering process classpath.
- Do not hand-edit ConfigMap Base64 values.
- Purge HA state after major upgrades (ha storage cleanup).
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
- Could not properly remove all state handles.
- Could not get the rest endpoint of ${clusterId}
- Could not create the RestClusterClient.
- The Flink cluster ${clusterId} already exists.
- Couldn't deploy Kubernetes Application Cluster. Expected dep
AI-assisted analysis of zhisheng17/flink-learning@d731cee761 (2026-09-06).
Data as JSON: /api/errors/40963249f7d1a2e5.
Report an issue: GitHub.