jenkinsci/jenkins · warning · IOException

Refusing to deserialize unsigned note from an old log.

Error message

Refusing to deserialize unsigned note from an old log.

What it means

IOException from ConsoleNote.readFrom when the INSECURE flag is false (the default, set by system property hudson.console.ConsoleNote.INSECURE) and a console note in the OLD unsigned format is encountered. Old logs predate note signing; default policy refuses to deserialize them to block deserialization attacks. The note is rejected, not the whole log.

Source

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

                    if (sz < 0) {
                        throw new IOException("Corrupt stream");
                    }
                } 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);
        }
    }

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Accept that old unsigned notes are skipped — the surrounding plain-text log still displays.
  2. If you fully trust the log source and only need it in a throwaway/test instance, set -Dhudson.console.ConsoleNote.INSECURE=true (security risk; not for production).
  3. Re-run the build to regenerate a signed log.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    note = ConsoleNote.readFrom(in);
} catch (IOException e) {
    // unsigned old note refused: skip, render plain text
}

Prevention

When it happens

Trigger: Viewing/parsing a very old build log (created before ConsoleNote signing) on a current Jenkins with INSECURE left at its default false.

Common situations: Old historical builds viewed after upgrade; logs restored from an ancient backup; migration from a pre-signing Jenkins version.

Related errors


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