PHPOffice/PHPWord · error · InvalidArgumentException

salt has to be of exactly 16 bytes length

Error message

salt has to be of exactly 16 bytes length

What it means

Metadata\Protection::setSalt validates that the salt used for password hashing is exactly 16 bytes. A null salt is allowed (no protection), but any non-null string of a different length is rejected because the underlying hashing algorithm expects a 16-byte salt.

Solutions

  1. Pass exactly 16 raw bytes, e.g. random_bytes(16)
  2. If you have hex, decode it first (hex2bin) so the result is 16 bytes
  3. Pass null explicitly if you want no salt rather than an empty string

Example fix

// before
$protection->setSalt('mysalt');
// after
$protection->setSalt(random_bytes(16));
Defensive patterns

Strategy: validation

Validate before calling

if ($salt !== null && strlen($salt) !== 16) { throw new \InvalidArgumentException('Salt must be 16 bytes'); }

Try / catch

try { $protection->setSalt($salt); } catch (\InvalidArgumentException $e) { $protection->setSalt(random_bytes(16)); }

Prevention

When it happens

Trigger: Calling setSalt() with a string shorter or longer than 16 characters, e.g. setSalt('shortsalt') or passing a hex string of 32 chars.

Common situations: Generating a salt with a function that returns a non-16-byte value; passing a UUID or hex-encoded bytes instead of raw 16 bytes; hand-typed salts in config.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of PHPOffice/PHPWord@aef95c0415 (2026-09-14). Data as JSON: /api/errors/f587febbe24406ea. Report an issue: GitHub.

Appendix: source

Thrown at src/PhpWord/Metadata/Protection.php:199

     *
     * @return string
     */
    public function getSalt()
    {
        return $this->salt;
    }

    /**
     * Set salt. Salt HAS to be 16 characters, or an exception will be thrown.
     *
     * @param string $salt
     *
     * @return self
     */
    public function setSalt($salt)
    {
        if ($salt !== null && strlen($salt) !== 16) {
            throw new InvalidArgumentException('salt has to be of exactly 16 bytes length');
        }

        $this->salt = $salt;

        return $this;
    }
}

View on GitHub (pinned to aef95c0415)