Tools Nimbus

Why is my SHA-256 hash different

Tools Nimbus is a free, no-signup developer toolkit that runs entirely in your browser, so your data is never uploaded to a server. A SHA-256 hash is deterministic, so two different results always mean two different inputs: a trailing newline, CRLF line endings, a text-encoding mismatch, or uppercase versus lowercase hex output. Paste each version into the Tools Nimbus Hash Generator, free with no signup, to find the byte that differs.

Last updated August 2026

A hash is deterministic. Different output means different input.

SHA-256 is a pure function of its input bytes. The same bytes always produce the same 256-bit digest, on any machine, in any language, forever. So when you get two different hashes for what looks like the same text, the text was not actually the same at the byte level. There is no randomness, no timestamp, and no per-run seed in a plain hash. That makes debugging refreshingly mechanical: instead of asking why the hash changed, find the byte that changed.

This is also why the two hashes look completely unrelated rather than "close." SHA-256 has an avalanche effect, so flipping a single input bit changes roughly half of the output bits. A one-character difference does not produce a one-character difference in the digest; it produces a totally different-looking string. Do not read anything into how similar or dissimilar the two hashes are.

Symptom, cause, and fix at a glance

SymptomMost likely causeFix
Hash of a file differs from hash of pasted textTrailing newline in the fileStrip or match the trailing newline on both sides
Hash differs between Windows and macOS/LinuxCRLF (\r\n) versus LF (\n) line endingsNormalize line endings before hashing
Hash differs between two apps or languagesDifferent text encoding (UTF-8 vs UTF-16, or a BOM)Encode as UTF-8 with no BOM on both sides
Hashes look equal but a string compare says noUppercase vs lowercase hex outputLowercase both, or compare raw bytes
Accented text hashes differentlyUnicode normalization (NFC vs NFD)Normalize to NFC before hashing
Server hash never matches yoursServer uses a salt, HMAC key, or hashes JSON, not raw textMatch the exact input and algorithm the server uses

Identify your cause by matching the digest

Because SHA-256 is deterministic, the same test string produces the same digest for everyone. That makes the mismatch identifiable by lookup: hash the word hello in whichever tool is giving you the unexpected answer, then find that digest in the table below. Whatever the row says was hashed is what your tool is actually feeding the algorithm, which is usually the whole diagnosis. Every value here is the real SHA-256 of the exact bytes described.

Bytes actually hashedSHA-256 (lowercase hex)What it means
hello (5 bytes, UTF-8)2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824The clean baseline, no newline
hello\n (6 bytes, LF)5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03A trailing newline was added, typically by echo or a text editor saving the file
hello\r\n (7 bytes, CRLF)cd2eca3535741f27a8ae40c31b0c41d4057a7a7b912b33b9aed86485d1c84676Windows line endings, often introduced by Git autocrlf
hello with a UTF-8 BOM (8 bytes)7489ebbcc2a00056ddaaaac190bce473e5c03696ea1bd8ed83cf59a174283862An invisible EF BB BFprefix from a Windows "Save as UTF-8"
hello as UTF-16LE (10 bytes)06e44dc1b95c469f43aaccb49e93c36827626266eed5575eced74af9a016c9cdThe text was encoded two bytes per character, classically by Windows PowerShell 5.1 redirection
hello (leading space)1c9c535c80b3298829957b9fbfcd00bec337baca0866812efc749b7669613d43Whitespace survived a copy-paste
Hello (capital H)185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969Case differs in the input, not just in the hex output

If your tool returns none of these for the input hello, the difference is upstream of encoding: you are probably hashing a file path rather than its contents, or the tool is applying a salt or HMAC key. If it returns the right digest but in uppercase, see cause 5, where nothing is wrong with the hash at all.

What each tool hashes by default

Most cross-tool mismatches come down to two defaults: whether the command appends a newline, and which case it prints. This table covers the common ones, using the string hello from the table above.

Tool or languageTypical commandDefault behavior to watch
GNU coreutils (Linux)echo hello | sha256sumecho appends LF, so you get the 6-byte digest. Use printf %s hello or echo -n for 5 bytes. Lowercase output
macOSshasum -a 256Same newline trap as above. Note shasum defaults to SHA-1 without -a 256. Lowercase output
PowerShellGet-FileHash -Algorithm SHA256 file.txtPrints uppercase hex, and hashes files only. In Windows PowerShell 5.1, "hello" > file.txt writes UTF-16LE with a BOM, which is the classic surprise digest
Pythonhashlib.sha256(b"hello").hexdigest()No newline added. Encoding is explicit, so "hello".encode() is UTF-8. Lowercase output
Node.jscreateHash("sha256").update("hello").digest("hex")Strings are treated as UTF-8 unless you pass another encoding. No newline added. Lowercase output
Browser (Web Crypto)crypto.subtle.digest("SHA-256", bytes)Takes bytes, not text, so TextEncoder makes it UTF-8. Returns a buffer you format yourself, so case is your choice

Cause 1: a trailing newline (the usual culprit)

This is the most common reason a hash of a file does not match a hash of the "same" text. A newline is a real byte, so echo "hello" | sha256sum hashes six bytes (hello\n) while pasting hello into a tool hashes five. The digests are entirely different. Text editors frequently add a final newline on save, and many shell tools do too. Use printf instead of echo (or echo -n) to drop the newline, and decide on one convention, with or without a trailing newline, for both sides.

Cause 2: CRLF versus LF line endings

Windows editors and Git configured with autocrlf store line breaks as \r\n (carriage return plus line feed), while macOS and Linux use a bare \n. That extra \r byte on every line changes the hash completely. If the same content hashes differently on two operating systems, or before and after a Git checkout, line endings are almost always the reason. Normalize to LF (or to CRLF) everywhere before hashing, and be aware that .gitattributes rules can silently rewrite line endings underneath you.

Cause 3: text encoding and byte-order marks

SHA-256 hashes bytes, not characters, so the encoding you use to turn text into bytes matters. The letter eis one byte in UTF-8 but two bytes in UTF-16, and a Windows "Save as UTF-8" may prepend a three-byte byte-order mark (EF BB BF) that you never see but that changes the hash. If two programs or two languages disagree on a hash, confirm both encode the string as UTF-8 with no BOM. This is the same class of bug that produces mojibake; see why Base64 decodes to garbled text for the encoding side of it.

Cause 4: Unicode normalization

Some accented and composed characters can be represented two ways that look identical on screen. The character é can be a single code point (NFC) or a plain e followed by a combining accent (NFD). Those are different byte sequences, so they hash differently even though the text is visually the same. macOS filenames, for instance, historically use NFD. If accented or non-Latin text hashes differently across systems, normalize both inputs to NFC (for example str.normalize("NFC") in JavaScript) before hashing.

Cause 5: uppercase versus lowercase hex

Sometimes the digests are actually identical and only their text representation differs. A SHA-256 result is 32 raw bytes; tools print those bytes as 64 hexadecimal characters, and some print a3f1... in lowercase while others print A3F1... in uppercase. A case-sensitive === or string equality check then reports a mismatch on hashes that are genuinely equal. Lowercase both strings before comparing them, or compare the raw byte arrays rather than the formatted hex.

Cause 6: the server is not hashing what you think

When your local hash never matches a server or database value, the two sides are probably not hashing the same thing. A password store applies a per-user salt (and usually a slow algorithm like bcrypt, not raw SHA-256), so the same password yields a different digest for every user by design. An API signature may be an HMAC, which mixes in a secret key. A record hash may cover a serialized JSON object whose key order or whitespace differs from your input. Match the exact bytes, salt, key, and algorithm the other side uses, and remember that a hash is one-way; see encoding vs encryption vs hashing for where hashing fits.

Find the difference in one step

You do not have to guess which cause you are hitting. Open the Hash Generator, paste each version of your text, and read the SHA-256 output for each. If the two hashes match, your inputs were identical and the mismatch was downstream (a case-sensitive compare, or a different algorithm). If they differ, the inputs differ, and the fastest way to see how is to drop both strings into the Diff Checker, which highlights a stray trailing newline, an extra space, or a swapped character that is invisible in a normal text field. Because both tools run entirely in your browser using the native Web Crypto API, the text you paste never leaves your device.

How to prevent it

  • Decide on a trailing-newline convention and apply it on both sides; printf and echo -n omit the newline that echo adds.
  • Normalize line endings (pick LF or CRLF) before hashing, and watch for Git autocrlf rewriting them.
  • Standardize on UTF-8 with no BOM end to end, and normalize Unicode to NFC when the text may contain accents.
  • Compare hashes case-insensitively, or compare raw bytes, so uppercase and lowercase hex never trip you up.
  • Confirm the algorithm and inputs match: a salted password hash or an HMAC will never equal a plain SHA-256 of the same text. For how the algorithms themselves differ, see SHA-1 versus SHA-256, and browse the Tools Nimbus guides for more developer fixes.

Frequently asked questions

Why do I get a different SHA-256 hash for the same text?+

SHA-256 is deterministic, so identical input bytes always produce identical output. If the hash changes, the bytes you fed in were not identical. The usual culprits are an invisible trailing newline your editor added, whitespace from a copy-paste, CRLF versus LF line endings, or a text-encoding difference such as UTF-8 versus UTF-16. Hash both versions side by side and compare the exact input, character by character, to find the byte that differs.

Why does my SHA-256 hash not match the server's hash?+

The server almost certainly hashed slightly different bytes than you did. Common causes are a trailing newline the server strips or keeps, a different character encoding, line endings rewritten in transit, or the server hashing a JSON representation (with different key order or spacing) rather than the raw string. Confirm you are both hashing the exact same UTF-8 bytes with no extra whitespace, and check whether the server uses a salt or HMAC key rather than a plain hash.

Does a trailing newline change a SHA-256 hash?+

Yes. A newline is a real byte (0x0A for LF, or 0x0D 0x0A for CRLF), so hashing "hello" and "hello\n" gives two completely different digests. Many editors and shell commands append a trailing newline automatically, which is the single most common reason a hash of a file does not match a hash of the same text typed into a tool. Strip or standardize the trailing newline on both sides.

Why is my SHA-256 hash uppercase in one tool and lowercase in another?+

The underlying digest is the same 32 bytes; only the hexadecimal text representation differs. One tool prints the bytes as lowercase hex (a3f1...) and another as uppercase (A3F1...). A case-sensitive string comparison then reports a mismatch even though the hashes are identical. Lowercase both strings before comparing, or compare the raw bytes rather than the formatted text.

Can whitespace or invisible characters change a hash?+

Yes, any difference in the input bytes changes the whole digest, including a leading space, a tab instead of spaces, a non-breaking space, a zero-width character, or a Unicode form difference (NFC versus NFD). Because SHA-256 has an avalanche effect, one changed byte flips roughly half the output bits, so the two hashes look totally unrelated even though the text looks identical.

Is it safe to check a hash in an online tool?+

It depends on whether the tool uploads your input. Tools Nimbus computes SHA-256 entirely in your browser using the native Web Crypto API, so the text you paste never leaves your device and is never sent to a server. Avoid any hasher that round-trips your data through a backend if the value is a secret, token, or private document.

Try these browser-based tools mentioned in this guide. Everything runs locally, so your data never leaves your device.