Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk4 min

How to Distinguish Missing and Null JSON Fields in Go

In Go’s traditional encoding/json API, distinguish an omitted JSON member from null by checking object-key presence separately from its decoded value.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

With Go’s traditional encoding/json API, a pointer field alone cannot tell you whether a JSON member was omitted or explicitly set to null: both commonly decode to nil. To preserve all three states—missing, null, and a concrete value—check object-member presence separately, for example by decoding into map[string]json.RawMessage.

What Go’s usual struct decoding preserves

JSON has three relevant states for a member: it can be absent, present with null, or present with a value. A Go field’s zero value does not record which input state produced it.

As an Amazon Associate I earn from qualifying purchases.

Pointer fields

For a fresh struct decoded with the traditional encoding/json API, an absent pointer field remains nil. An explicit JSON null also leaves a pointer nil, so the pointer does not distinguish those cases. The Go project’s tutorial explains the absent case: “If there were a Bar field in the JSON object, Unmarshal would allocate a new Bar and populate it. If not, Bar would be left as a nil pointer.” Go JSON tutorial

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use *T when the distinction you need is simply whether a non-null value was decoded. Do not treat it as a three-state presence indicator.

Scalar fields

For a fresh struct, an omitted scalar remains at its zero value. In v1, unmarshaling JSON null into a non-pointer scalar has no effect, so it also remains at that zero value. For example, a missing name and a null name can both leave a string field empty.

Decode into a newly initialized destination when behavior must not depend on old field contents. Decoding into a reused value can preserve preexisting state where input does not update a field, making conclusions based on the resulting value unreliable.

Choose a representation based on the states you need

Requirement Representation What it preserves
Know whether a non-null value was populated *T field Nil versus decoded non-null value; not missing versus explicit null in the common v1 case.
Distinguish missing, null, and value map[string]json.RawMessage and key lookup Member presence, raw JSON payload, and—after decoding—its typed value.
Keep a typed struct interface and track presence Custom wrapper with UnmarshalJSON All three states, if the wrapper explicitly records presence and null/value state.
Read an open-ended object before choosing fields map[string]json.RawMessage or a generic JSON map Object member presence and raw payloads; selected values still need validation.

Distinguish the three states with RawMessage

A map lookup’s boolean result tells you whether the key exists. If it does, compare the raw JSON to null; otherwise decode the non-null value into the field’s actual type. This keeps presence separate from type conversion.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import (
    "bytes"
    "encoding/json"
)

var fields map[string]json.RawMessage
if err := json.Unmarshal(data, &fields); err != nil {
    return err
}

raw, present := fields["name"]
switch {
case !present:
    // The member was missing.
case bytes.Equal(bytes.TrimSpace(raw), []byte("null")):
    // The member was present with explicit JSON null.
default:
    // The member was present with a non-null JSON value.
    var name string
    if err := json.Unmarshal(raw, &name); err != nil {
        return err
    }
    // Use name.
}

The imports are bytes and encoding/json. Return type errors from decoding rather than silently accepting a value of the wrong JSON type. If the endpoint requires the top-level input to be an object, validate that contract too; decide explicitly how it should handle a top-level null or another JSON type.

When a custom wrapper is clearer

For a typed API, define a wrapper whose UnmarshalJSON method records whether the field was present and whether its payload was null or a concrete value. A mere value field inside the wrapper is not enough: its zero value still cannot indicate absence. For many fields or nested objects, a typed wrapper—or a two-pass decode that first captures presence and then populates typed values—can be easier to maintain than repeated map checks.

Apply the states to PATCH semantics

Go does not choose what missing or null means for an application. A common PATCH contract is that a missing member leaves the stored value unchanged, null clears it, and a concrete value replaces it. The handler must receive a representation that preserves those distinctions, then implement the contract deliberately. If an API instead treats null and missing alike, a pointer may be sufficient for that narrower requirement.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Keep the JSON API version explicit

These decoding details describe the traditional encoding/json API, commonly called v1. Go documents encoding/json/v2 separately, and its behavior can differ, including null handling and merging into preexisting values. The Go blog’s August 2026 note says Go 1.27 introduces the v2 package; check the package documentation for the exact Go toolchain and API you target rather than carrying v1 assumptions across. Go blog: JSON v2

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Likewise, omitempty is a marshaling option, not a way to detect whether an input field was present. The v1 and v2 APIs define omission differently when marshaling, but neither gives omitempty a presence-detection role during unmarshaling. See the v1 package documentation and v2 package documentation.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.