{"record":{"id":"41133fab3dcb463f","repo":"SixLabors/ImageSharp","slug":"bit-depth-is-not-supported-or-not-valid","errorCode":null,"errorMessage":"Bit depth is not supported or not valid.","messagePattern":"Bit depth is not supported or not valid\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/ImageSharp/Formats/Png/PngEncoderCore.cs","lineNumber":1797,"sourceCode":"            byte quantizedBits = (byte)Numerics.Clamp(ColorNumerics.GetBitsNeededForColorDepth(quantizedFrame!.Palette.Length), 1, 8);\n            byte bits = Math.Max(bitDepth, quantizedBits);\n\n            // Png only supports in four pixel depths: 1, 2, 4, and 8 bits when using the PLTE chunk\n            // We check again for the bit depth as the bit depth of the color palette from a given quantizer might not\n            // be within the acceptable range.\n            bits = bits switch\n            {\n                3 => 4,\n                >= 5 and <= 7 => 8,\n                _ => bits\n            };\n\n            bitDepth = bits;\n        }\n\n        if (Array.IndexOf(PngConstants.ColorTypes[colorType], bitDepth) < 0)\n        {\n            throw new NotSupportedException(\"Bit depth is not supported or not valid.\");\n        }\n\n        return bitDepth;\n    }\n\n    /// <summary>\n    /// Calculates the correct number of bytes per pixel for the given color type.\n    /// </summary>\n    /// <param name=\"pngColorType\">The color type.</param>\n    /// <param name=\"use16Bit\">Whether to use 16 bits per component.</param>\n    /// <returns>Bytes per pixel.</returns>\n    private static int CalculateBytesPerPixel(PngColorType? pngColorType, bool use16Bit)\n        => pngColorType switch\n        {\n            PngColorType.Grayscale => use16Bit ? 2 : 1,\n            PngColorType.GrayscaleWithAlpha => use16Bit ? 4 : 2,\n            PngColorType.Palette => 1,\n            PngColorType.Rgb => use16Bit ? 6 : 3,","sourceCodeStart":1779,"sourceCodeEnd":1815,"githubUrl":"https://github.com/SixLabors/ImageSharp/blob/59ce6af6fc29027cda277ef62d4d1694a8acce91/src/ImageSharp/Formats/Png/PngEncoderCore.cs#L1779-L1815","documentation":"PngEncoderCore's bit-depth selection helper throws this NotSupportedException when the chosen (colorType, bitDepth) pair is not in PngConstants.ColorTypes — i.e. the depth is not legal for that PNG color type (for example 16-bit palette, or 1/2/4-bit RGB). It is the encoder-side mirror of the IHDR validation the decoder performs.","triggerScenarios":"Saving to PNG with PngEncoder BitDepth/ColorType options that combine illegally, e.g. `new PngEncoder { ColorType = PngColorType.Palette, BitDepth = PngBitDepth.Bit16 }`, or quantized 1/2/4-bit output requested for an unsupported color type.","commonSituations":"Hand-built PngEncoder option sets, porting settings from another library's API, or blindly reusing previously captured encoder options across differently processed images.","solutions":["Use a valid color type/bit depth combination (palette: 1/2/4/8; grayscale: 1/2/4/8/16; gray-alpha, RGB, RGBA: 8 or 16).","Omit BitDepth (leave default) and let the encoder derive a valid depth from the pixel type.","If palette output is needed at 8-bit, set BitDepth = Bit8, or switch ColorType to Rgb/RgbWithAlpha for 16-bit.","Log and validate the encoder options against PngConstants.ColorTypes before calling Save."],"exampleFix":"// before\nvar encoder = new PngEncoder { ColorType = PngColorType.Palette, BitDepth = PngBitDepth.Bit16 };\nimage.SaveAsPng(\"out.png\", encoder); // throws\n// after\nvar encoder = new PngEncoder { ColorType = PngColorType.Palette, BitDepth = PngBitDepth.Bit8 };\nimage.SaveAsPng(\"out.png\", encoder);","handlingStrategy":"validation","validationCode":"// validate encoder options against the spec table before saving\nstatic bool IsValidPngDepth(PngColorType t, PngBitDepth d) => t switch\n{\n    PngColorType.Palette => d is PngBitDepth.Bit1 or PngBitDepth.Bit2 or PngBitDepth.Bit4 or PngBitDepth.Bit8,\n    PngColorType.Grayscale => true,\n    _ => d is PngBitDepth.Bit8 or PngBitDepth.Bit16\n};","typeGuard":"static bool IsValidPngDepth(PngColorType t, PngBitDepth d) =>\n    t == PngColorType.Palette\n        ? d is PngBitDepth.Bit1 or PngBitDepth.Bit2 or PngBitDepth.Bit4 or PngBitDepth.Bit8\n        : d is PngBitDepth.Bit8 or PngBitDepth.Bit16;","tryCatchPattern":"try\n{\n    image.SaveAsPng(path, encoder);\n}\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"Bit depth\"))\n{\n    image.SaveAsPng(path, new PngEncoder()); // defaults derive a valid depth\n}","preventionTips":["Leave PngEncoder.BitDepth unset and let the encoder derive it from the pixel type.","For palette output always use 1/2/4/8-bit depths; reserve 16-bit for grayscale/RGB/RGBA.","Centralize encoder option construction so invalid colorType+depth pairs cannot be assembled ad hoc."],"tags":["png","encoder","bit-depth","configuration"],"backgroundTag":"invalid-config-value","analyzedSha":"59ce6af6fc29027cda277ef62d4d1694a8acce91","analyzedAt":"2026-09-13T18:34:59.331Z","contentChangedAt":"2026-09-13T18:34:59.331Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}