jenkinsci/jenkins · error · IOException

MAC mismatch

Error message

MAC mismatch

What it means

IOException from ConsoleNote.readFrom when INSECURE is false and the note's MAC does not verify against its payload (MAC.checkMac fails). This indicates the payload was tampered with, or the note was signed with a different Jenkins secret key than the one currently verifying.

Source

Thrown at core/src/main/java/hudson/console/ConsoleNote.java:274

                    }
                } else {
                    mac = null;
                    sz = -macSz;
                }
                buf = new byte[sz];
                decoded.readFully(buf);
            }

            byte[] postamble = new byte[POSTAMBLE.length];
            in.readFully(postamble);
            if (!Arrays.equals(postamble, POSTAMBLE))
                return null;    // not a valid postamble

            if (!INSECURE) {
                if (mac == null) {
                    throw new IOException("Refusing to deserialize unsigned note from an old log.");
                } else if (!MAC.checkMac(buf, mac)) {
                    throw new IOException("MAC mismatch");
                }
            }

            Jenkins jenkins = Jenkins.getInstanceOrNull();

            try (ObjectInputStream ois = new ObjectInputStreamEx(new GZIPInputStream(new ByteArrayInputStream(buf)),
                    jenkins != null ? jenkins.pluginManager.uberClassLoader : ConsoleNote.class.getClassLoader(),
                    ClassFilter.DEFAULT)) {
                return getConsoleNote(ois);
            }
        } catch (Error e) {
            // for example, bogus 'sz' can result in OutOfMemoryError.
            // package that up as IOException so that the caller won't fatally die.
            throw new IOException(e);
        }
    }

    @SuppressFBWarnings(value = "OBJECT_DESERIALIZATION", justification = "Deserialization is protected by logic.")

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Do not transport logs across instances with different signing secrets; keep logs with their original instance.
  2. Regenerate logs by re-running the build on the current instance.
  3. Only as a last resort in a trusted test setup, set -Dhudson.console.ConsoleNote.INSECURE=true (disables MAC verification — insecure).
Defensive patterns

Strategy: try-catch

Try / catch

try {
    note = ConsoleNote.readFrom(in);
} catch (IOException e) {
    // MAC failed: treat note as untrusted, skip rendering it
}

Prevention

When it happens

Trigger: Reading a console log whose notes were signed by a different Jenkins instance/key; a log copied between instances; the Jenkins secret key was rotated/lost; the log bytes were altered.

Common situations: Copying build logs across instances with different secrets; restoring logs without the matching secret; tampering; key resharding that changed the MAC key.

Related errors


AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14). Data as JSON: /api/errors/2a3e5029063f8e12. Report an issue: GitHub.