How to Read and Write NFC Tags

Step-by-step operational guide

| 3 min read

How to Read and Write NFC Tags

Reading and writing NFC tags requires understanding the NDEF data model, your platform's NFC API, and common failure modes. This guide covers the complete workflow from tapping a tag to persisting structured data.

Reading Tags

When an nfc-enabled-device enters reader-writer-mode, it polls for tags at 106–424 kbit/s. Once a tag responds, the reader retrieves the tag's uid and reads the NDEF memory area.

The NDEF memory contains a sequence of ndef-records wrapped in an ndef-message. Each record carries a Type Name Format (tnf), a type string, an optional ID, and a payload. Common record types:

TNF Type Payload Example
1 (Well Known) U URI https://nfcfyi.com
1 (Well Known) T Text en:Hello NFC
2 (MIME) text/vcard vCard blob Contact card
4 (External) nfcfyi.com:cfg Custom bytes App config

On Android, a successful read delivers an NfcAdapter.ACTION_NDEF_DISCOVERED intent containing a NdefMessage. On iOS (Core NFC), NFCNDEFReaderSession calls readerSession(_:didDetectNDEFs:). Both platforms expose the raw NdefRecord array.

Writing Tags

Before writing, verify that the tag is not locked. Tags expose lock-bits that, once set, make the memory permanently read-only. A capability-container at the start of the NDEF area declares memory size, access conditions, and whether the tag is NDEF-formatted.

Writing workflow: 1. Authenticate if the tag has a password (PWD_AUTH for NTAG, AUTHENTICATE for DESFire). 2. Format the tag if it has no capability container (first use). 3. Construct an NdefMessage with one or more NdefRecords. 4. Write the message using the platform API (Ndef.writeNdefMessage() on Android, NFCNDEFTag.writeNDEF() on iOS). 5. Optionally set the otp lock page to protect the content.

NDEF Basics

The NDEF specification defines a compact binary encoding. Each record begins with a flags byte encoding MB (Message Begin), ME (Message End), CF (Chunk Flag), SR (Short Record), IL (ID Length), and TNF. A short record stores the payload length in 1 byte (max 255 B); a normal record uses 3 bytes (max 16 MB).

The most important record types for getting started:

  • ndef-uri — Encodes a URL with a 1-byte prefix abbreviation (e.g., 0x03 = https://)
  • ndef-text — Encodes a UTF-8 or UTF-16 string with an IANA language code
  • smart-poster — Composite record combining URI + Text title + optional action

Common Errors

Error Cause Fix
TagLostException Tag moved before write completed Hold steady; retry
FormatException Malformed NDEF message Validate with NDEF Decoder
ReadOnlyException Lock bits set Use a different tag
Write returns success but read fails Buffer too small for payload Check user-memory with Memory Calculator
Auth failure Wrong password Reset via backdoor if available (chip-specific)

Use the NDEF Message Encoder to construct and preview NDEF payloads before writing, and the NDEF Message Decoder to inspect raw bytes from an existing tag.

See also: Your First NFC Project and Android NFC Programming Guide.

Terms in This Guide