Error HTTP 431 (Request Header Fields Too Large) terjadi ketika ukuran total HTTP header yang dikirimkan oleh klien melampaui alokasi memori buffer pada server atau reverse proxy. Pada ekosistem React Native, penyebab paling umum dari masalah ini bukanlah penambahan custom header yang disengaja oleh developer, melainkan fenomena cookie bloat yang terakumulasi di dalam native cookie jar.

Gejala dan Investigasi Root Cause

Gejala umum diawali dengan kegagalan request API secara mendadak pada klien tertentu, sementara pengguna lain tetap berjalan normal. Pada reverse proxy seperti Nginx, request di-drop sebelum diteruskan ke upstream service dengan status kode 400 Bad Request atau 431 Request Header Fields Too Large.

1. Analisis Log Reverse Proxy dan Backend

Periksa access log reverse proxy untuk memastikan ukuran request header. Pada Nginx, variabel $request_length mencatat total bytes yang diterima dari klien:

# Cuplikan log format Nginx
log_format debug_header '$remote_addr - [$time_local] "$request" '
                        '$status $bytes_sent $request_length '
                        '"$http_cookie"';

Jika log mencatat error client intended to send too large header, request tersebut dibatalkan oleh Nginx karena melebihi batas direktif client_header_buffer_size atau large_client_header_buffers. Pada Node.js native HTTP runtime, error ini memicu event HPE_HEADER_OVERFLOW atau status 431 otomatis.

2. Mekanisme Native Cookie Jar di React Native

Ketika aplikasi React Native mengeksekusi request via fetch atau axios, runtime JavaScript mendelegasikan networking ke modul platform native:

  • iOS: Menggunakan NSURLSession yang terikat langsung ke singleton NSHTTPCookieStorage.sharedHTTPCookieStorage.
  • Android: Menggunakan OkHttp Client yang umumnya terintegrasi dengan CookieManager / JavaNetCookieJar.

Setiap kali endpoint mengembalikan header Set-Cookie (baik dari API gateway, load balancer seperti AWS ALB, autentikasi session, atau third-party WebViews), native layer menyimpan cookie tersebut secara persisten. Jika backend mengeluarkan session cookie atau token rotasi tanpa atribut Expires/Max-Age yang ketat, atau jika path cookie terduplikasi (misal / vs /api), cookie lama tidak terhapus. Header Cookie akan dikirim ulang secara utuh pada setiap request berikutnya hingga ukurannya membengkak melewati 8 KB - 16 KB.

Langkah 1: Mitigasi Cepat Sisi Backend (Buffer Tuning)

Tuning buffer backend berfungsi sebagai mitigasi darurat agar user yang terdampak dapat kembali mengakses API sebelum update aplikasi mobile dirilis.

Konfigurasi Nginx

Tingkatkan kapasitas penampungan header klien pada file konfigurasi Nginx:

http {
    # Default biasanya 1k
    client_header_buffer_size 4k;

    # Alokasikan hingga 4 buffer masing-masing sebesar 16k
    large_client_header_buffers 4 16k;
}

Konfigurasi Node.js

Node.js membatasi ukuran header default sebesar 16 KB (atau 8 KB pada versi lama). Batas ini dapat dinaikkan saat runtime dijalankan:

node --max-http-header-size=32768 server.js
Peringatan Keamanan: Meningkatkan header buffer secara global meningkatkan konsumsi memori per koneksi dan membuka celah serangan Slowloris atau Denial of Service (DoS). Jadikan langkah ini solusi sementara, bukan solusi permanen.

Langkah 2: Solusi Definitif Sisi React Native

Akar masalah harus diperbaiki di sisi klien dengan membersihkan dan mengontrol native cookie jar.

1. Pasang Library Manajemen Cookie

React Native standar tidak menyediakan API JavaScript untuk memanipulasi native cookie jar secara granular. Gunakan pustaka native:

npm install @react-native-cookies/cookies
# atau
yarn add @react-native-cookies/cookies

Untuk iOS, jalankan instalasi Pods:

npx pod-install

2. Implementasi Cookie Sanitizer

Buat utilitas untuk memeriksa ukuran cookie dan membersihkannya jika terdeteksi bloat, atau kosongkan saat proses autentikasi (login/logout):

import CookieManager from '@react-native-cookies/cookies';

const MAX_SAFE_COOKIE_BYTES = 4096; // 4 KB safety threshold

export async function auditAndCleanCookies(domainUrl: string): Promise<void> {
  try {
    const cookies = await CookieManager.get(domainUrl);
    const serializedCookies = Object.entries(cookies)
      .map(([key, cookie]) => `${key}=${cookie.value}`)
      .join('; ');

    const cookieSizeBytes = new Blob([serializedCookies]).size;

    if (cookieSizeBytes > MAX_SAFE_COOKIE_BYTES) {
      // Hapus seluruh cookie jika akumulasi sudah kritis
      await CookieManager.clearAll();
      console.warn(`[Network] Cookie bloat detected (${cookieSizeBytes} bytes). Native jar cleared.`);
    }
  } catch (error) {
    console.error('[Network] Gagal mengaudit native cookies:', error);
  }
}

3. Eksekusi pada Bootstrapping dan Auth Interceptor

Panggil fungsi pembersihan pada lifecycle utama aplikasi atau pasang pada response interceptor ketika status 431 tertangkap:

import axios from 'axios';
import { auditAndCleanCookies } from './cookieUtils';

const apiClient = axios.create({
  baseURL: 'https://api.example.com',
});

apiClient.interceptors.response.use(
  (response) => response,
  async (error) => {
    if (error.response && error.response.status === 431) {
      // Bersihkan cookie segera jika backend menolak request
      await auditAndCleanCookies('https://api.example.com');
    }
    return Promise.reject(error);
  }
);

Praktik Terbaik Pencegahan

  • Pemisahan Token: Jika arsitektur API menggunakan Bearer Token (JWT) di header Authorization, pastikan backend tidak mengirimkan header Set-Cookie yang tidak diperlukan ke aplikasi mobile.
  • Isolasi Cookie WebView: Jika menggunakan react-native-webview, pastikan session cookie dari third-party web pages tidak berbagi domain yang sama dengan endpoint core API untuk mencegah kontaminasi header request native.
  • Atribut Cookie yang Benar: Selalu set atribut Path, Domain, dan Max-Age secara presisi pada server backend agar cookie usang langsung di-invalidate oleh native platform HTTP client.