Go

Go 1.25の新機能と変更点|サポート終了後の脆弱性と1.24から上げると変わる箇所を実測

Go 1.25の新機能と変更点|サポート終了後の脆弱性と1.24から上げると変わる箇所を実測

Go 1.25は2025年8月12日に公開されたリリースです(Go 1.25リリースノート)。言語仕様の変更はなく、ランタイム・ツール・標準ライブラリの更新が中心ですが、1.24から上げるとエラー確認前にポインタを触るコードがpanicする、go.modのgo行によってGOMAXPROCSの既定値が変わるといった、動作に出る変更が含まれます。この記事では、go1.24.13とgo1.25.14で同じコードを実行した出力を並べて、移行時に確かめる箇所と主要な新機能を説明します。

Go 1.25は2026年8月19日のGo 1.27公開でサポートが終わり、その後に出たセキュリティ修正は1.25系に入っていません。現行版の変更点と更新手順はGo 1.27の新機能・変更点まとめにまとめています。Go自体の導入から始める場合はGo言語の実装入門が入口です。

まとめ:Go 1.25で押さえる要点

  • リリースは2025年8月12日、最終パッチは2026年8月19日のgo1.25.14。以後のセキュリティ修正は1.26系・1.27系にしか出ておらず、HTTPサーバーを動かす検証コードをgovulncheckで調べると、呼び出し経路のある未修正の脆弱性が8件見つかりました。
  • Go 1.21〜1.24のコンパイラにあったnilチェック遅延のバグが直り、errを確かめる前に戻り値のポインタを使うコードがpanicします。go.modのgo行が1.24のままでも起きます。
  • 要素数が変数のmakeもスタックに置かれるようになり、32バイトの一時スライスはヒープ割り当てが0回になりました。unsafe.Pointerの誤用が表に出やすくなる変更でもあります。
  • コンテナのCPU上限に合わせたGOMAXPROCS、TLS 1.2のSHA-1署名拒否などは、go.modのgo行が1.25以上のときだけ有効です。ツールチェーンを上げただけでは切り替わりません。
  • testing/synctestが正式機能になり、1時間待つテストを仮想時計で即座に終えられます。sync.WaitGroup.Goとgo vetのwaitgroup・hostportも追加されました。
  • 実験機能だったGreen Tea GCはGo 1.26で既定に、encoding/json/v2はGo 1.27で正式版になりました。1.25で試すときの切り替え方は後続版と違います。

以下、移行時に挙動が変わる箇所から順に説明します。

Go 1.25のサポート終了日と終了後に残る脆弱性

Goは「各メジャーリリースは、2つ新しいメジャーリリースが出るまでサポートする」方針です(Goのリリース履歴)。1.25はGo 1.27が出た2026年8月19日にサポートが終わり、それ以降の修正は1.26系と1.27系にだけ出ています。

リリース日とサポート終了日

版 公開日 1.25にとっての意味
go1.25.0 2025-08-12 初版
go1.26.0 2026-02-10 1.25はサポート中
go1.25.14 2026-08-19 1.25系の最後のパッチ
go1.27.0 2026-08-19 1.25のサポート終了
go1.26.9・go1.27.2 2026-10-08 1.25系には修正なし
go1.26.10・go1.27.3 2026-10-19 1.25系には修正なし

govulncheckで見るgo1.25.14の未修正脆弱性

サポート終了の影響を数で見るため、http.ListenAndServeとx509.ParseCertificateを呼ぶだけの小さなプログラムを、go.modのgo行を1.25にしてgovulncheck v1.9.0(脆弱性データベースは2026年10月27日更新)で調べました。

$ GOTOOLCHAIN=go1.25.14 govulncheck ./...
Vulnerability #1: GO-2026-6809
    Distrust compromised intermediate certificates in crypto/x509
  Standard library
    Found in: crypto/[email protected]
    Fixed in: crypto/[email protected]

Vulnerability #2: GO-2026-6617
    HTTP/2 server crash due to HPACK encoder race in net/http
  Standard library
    Found in: net/[email protected]
    Fixed in: net/[email protected]
(中略)
Your code is affected by 8 vulnerabilities from the Go standard library.

$ GOTOOLCHAIN=go1.27.3 govulncheck ./...
No vulnerabilities found.

呼び出し経路のある8件のうち7件はnet/http・crypto/tls・mime/multipartの脆弱性で2026年10月8日のgo1.26.9、1件はcrypto/x509の脆弱性で10月19日のgo1.26.10が修正版です。たとえばGO-2026-6809の影響範囲は「go1.26.10より前、およびgo1.27.0以上go1.27.3未満」で、1.25系の修正版はありません。同じコードをgo1.27.3で調べると0件でした。HTTPサーバーを公開しているサービスで1.25.14を使い続けると、今後その版にも影響する脆弱性が見つかっても、Goプロジェクトから修正版が提供されません。

注意点として、govulncheck v1.9.0はgo.modでgo 1.26.0を要求します。GOTOOLCHAIN=go1.25.14のままgo installするとrequires go >= 1.26.0で入らないため、1.26以降でインストールし、調べるときだけ対象のツールチェーンへ切り替えます。終了コードの扱いやCIへの組み込みはgovulncheckの使い方【v1.9.0】終了コード・ignore代替・Actions設定で説明しています。

Cloud Run・App Engineのgo125ランタイムの期限

Google Cloudのマネージドランタイムには、Go本体とは別の期限があります。次の表のCloud Runの期限はGoogle管理のベースイメージを使うワークロードが対象で、独自のコンテナイメージを直接デプロイする場合には適用されません。

サービス ランタイムID 1つ目の期限 2つ目の期限
Cloud Run go125 非推奨 2026-10-01 廃止 2027-04-01
App Engineスタンダード go125 サポート終了 2027-03-02 非推奨 2028-03-02

Cloud Runのランタイムサポート表では、go125は2026年10月1日に非推奨期間へ入っており、2027年4月1日の廃止以降は、このランタイムでワークロードを新規作成・更新できないと書かれています。App Engineのサポートスケジュールはgo125のサポート終了を2027年3月2日としています。どちらもGo本体のサポート終了より後ですが、延びるのはデプロイできる期間で、Goプロジェクトが1.25系の修正版を出さない点は変わりません。期限が近いCloud Runのサービスから、go126かgo127へ切り替えるのが安全な順番です。

複数のサービスでGoの版がそろっていない場合は、go.modのgo行とビルドに使うツールチェーンを先に一覧にします。1.24以前から一気に上げる場合も、次章の挙動の変化はそのまま当てはまります。社内で棚卸しと更新を進める手が足りないときは、システムマイグレーション・リプレイスの支援もご相談いただけます。

1.24から上げると挙動が変わる箇所

Go 1.25のリリースノートは「ほぼすべてのGoプログラムはこれまでどおりコンパイル・実行できる」としています。ただし、次の5点は出力や動作が変わります。どれもリリースノートでは別々の節に書かれているため、移行の確認項目として1か所にまとめます。

nilチェック遅延バグの修正でpanicするコード

Go 1.21で入ったコンパイラのバグにより、1.21〜1.24ではnilポインタの検査が後ろへずれることがありました。リリースノートに載っている次のコードは、ファイルが無いのでfはnilですが、1.24では何事もなく終了します。

package main

import "os"

func main() {
	f, err := os.Open("nonExistentFile")
	name := f.Name()
	if err != nil {
		return
	}
	println(name)
}

同じコードを2つのツールチェーンで実行した結果です。GOTOOLCHAINに版を指定すると、goコマンドがその版を取得して実行します(仕組みはGOTOOLCHAINとは|Go toolchainの自動切り替えとgo.modのtoolchain行)。

$ GOTOOLCHAIN=go1.24.13 go run .
(何も出力されず終了コード0)

$ GOTOOLCHAIN=go1.25.14 go run .
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x3732665]

goroutine 1 [running]:
os.(*File).Name(...)

これは言語仕様どおりの挙動に戻す修正で、go.modのgo行を1.24のままにしてgo1.25.14でビルドしても同じくpanicしました。go行で旧挙動に戻すことはできません。対処は、エラーを返す呼び出しの直後にerrを確かめる順序へ書き直すことです。Go言語のエラーハンドリング実装ガイドで扱っている、呼び出しの直後にerrを判定する形にしておけば、この修正の影響は受けません。

スライスのスタック割り当て拡大とunsafe.Pointerの誤用

1.25のコンパイラは、要素数が変数のmakeでも、スライスが関数の外へ逃げなければ、小さいバッキング配列をスタックに置くようになりました。次の関数をインライン化させずにベンチマークすると、ヒープ割り当ての回数が変わります。

//go:noinline
func Sum(n int) int {
	buf := make([]int, n)
	for i := range buf {
		buf[i] = i
	}
	s := 0
	for _, v := range buf {
		s += v
	}
	return s
}
$ GOTOOLCHAIN=go1.24.13 go build -gcflags=-m .
./s.go:5:13: make([]int, n) escapes to heap
$ GOTOOLCHAIN=go1.25.14 go build -gcflags=-m .
./s.go:5:13: make([]int, n) does not escape

(ベンチマークのB/opとallocs/op)
              Sum(4)=32バイト    Sum(64)=512バイト
go1.24.13     32 B  / 1 alloc     512 B / 1 alloc
go1.25.14      0 B  / 0 alloc     512 B / 1 alloc

今回のdarwin/amd64環境ではintは1個8バイトで、int 4個(32バイト)のSum(4)はヒープ割り当てが0回になり、512バイトのSum(64)は従来どおり1回でした。go.modのgo行は1.24のままで、この変更はgo行に関係なくコンパイラ側で効きます。

リリースノートは、この変更がunsafe.Pointerの誤った使い方の影響を増幅しうるとし、例としてissue 73199を挙げています。1.25へ上げてからメモリ破壊のようなクラッシュが出たら、-gcflags=all=-d=variablemakehash=nで新しいスタック割り当てを止めて再現するかを確かめます。上のベンチマークにこのフラグを付けると、Sum(4)は32 B/op・1 allocs/opに戻りました。原因の割り当てを絞り込むときは、bisectツールに-compile=variablemakeを渡します。

go.modのgo行で切り替わる既定値(DefaultGODEBUG)

Goは互換性を保つため、挙動を変える修正の多くをGODEBUG設定で包み、go.modのgo行が古いモジュールでは旧挙動を既定にします。go行をgo 1.24のままgo1.25.14でビルドしたバイナリをgo version -mで見ると、次の設定が埋め込まれていました。

$ go version -m b125
...
	build	DefaultGODEBUG=containermaxprocs=0,decoratemappings=0,tlssha1=1,updatemaxprocs=0,x509sha256skid=0

go行をgo 1.25にするとこの行は消え、1.25の新しい既定値が有効になります。各設定の意味はGoのGODEBUG一覧に載っています。

設定 go 1.24行のとき go 1.25行のとき
containermaxprocs 0(cgroup上限を見ない) 1(上限を見る)
updatemaxprocs 0(更新しない) 1(定期的に更新)
tlssha1 1(SHA-1署名を許可) 既定で拒否
x509sha256skid 0(SHA-1で生成) SHA-256で生成
decoratemappings 0(名前なし) Linuxでメモリ領域に名前

つまり、ツールチェーンだけを1.25に上げても、コンテナ対応のGOMAXPROCSは動きません。逆に、go行を1.25へ上げた時点でTLS 1.2のSHA-1署名(RFC 9155)が拒否されるため、古い機器と通信するクライアントはこのタイミングで接続に失敗する可能性があります。その場合はGODEBUG=tlssha1=1で一時的に戻せます。

recoverしたpanicを投げ直したときの表示

recoverしたpanicを同じ値で投げ直すと、1.24まではメッセージが2行に重複して出ていました。1.25では1行にまとまります。

$ GOTOOLCHAIN=go1.24.13 go run .
panic: PANIC [recovered]
	panic: PANIC

$ GOTOOLCHAIN=go1.25.14 go run .
panic: PANIC [recovered, repanicked]

ログ監視で[recovered]の直後の行をパターンにしている場合は、1.25で一致しなくなります。

macOS 12未満の切り捨てとwindows/armの最終版

Go 1.25の実行にはmacOS 12 Monterey以降が必要です。32ビットのwindows/arm(GOOS=windows GOARCH=arm)は1.25が最後の収録で、1.26で削除されました。さらに1.26は「macOS 12で動く最後のリリース」とされ、1.27ではmacOS 13 Ventura以降が必要です(Go 1.27のリリースノート)。古いmacOSのビルド機を残している場合、1.25から先は版ごとに足切りが進む点に注意してください。

コンテナ対応GOMAXPROCS:Kubernetesのlimitsによる既定値の変更

1.24までのGOMAXPROCSは、起動時の論理CPU数(runtime.NumCPU)が既定でした。Kubernetesでlimits.cpuを2に絞っても、ノードが64コアならGOMAXPROCSは64になり、CPUクォータを使い切ってスロットリングされる原因になっていました。

1.25(go行が1.25以上)では、Linuxでプロセスが属するcgroupのCPU帯域上限を読み、論理CPU数より小さければそちらを既定にします。go1.25.14のsrc/runtime/cgroup_linux.goでは、上限(quota÷period)の端数を切り上げ、2未満は2にしてから論理CPU数と比べています。

ノードの論理CPU limits.cpu 1.24の既定 1.25の既定
64 2 64 2
64 2.5 64 3
64 0.5 64 2
64 指定なし 64 64

表は、プロセスが64個の論理CPUすべてを利用でき、GOMAXPROCSやGODEBUGを上書きしていない場合の計算値です。CPU affinityで利用可能CPUが制限される場合は、その数も既定値に影響します。見るのはCPUの上限(limits)だけで、requestsは考慮しません(リリースノートに明記)。requestsだけを設定しているPodでは何も変わりません。Kubernetesでlimitsを付けていない構成なら、1.25へ上げてもGOMAXPROCSは従来どおりです。

もう1つの変更として、ランタイムは論理CPU数やCPU affinityの変化を定期的に確認し、GOMAXPROCSを更新します。LinuxではcgroupのCPU帯域上限の変化も反映します。環境変数GOMAXPROCSやruntime.GOMAXPROCSで手動設定するとどちらも無効になり、個別に止めるにはGODEBUG=containermaxprocs=0とupdatemaxprocs=0を使います。手動設定を解除して新しい既定値に戻すためのruntime.SetDefaultGOMAXPROCSも追加されました。GOMAXPROCSがスケジューラのPの数を決める仕組みはGMPモデルの解説で説明しています。

testing/synctestとテスト関連の追加

synctest.Testで時間を仮想化

testing/synctestは1.24でGOEXPERIMENT=synctest付きの実験機能として入り、1.25で正式機能になりました。synctest.Testの中(バブル)ではtimeパッケージが偽の時計で動き、バブル内の全ゴルーチンがdurably blocked(バブル内部の処理だけで解除される待機状態)になると、次のタイマー時刻まで時計が進みます。ネットワークI/OやMutexのロック待ちは、この条件に含まれません。1時間のタイムアウトを持つcontextの期限切れを確かめるテストは次のように書けます。

func TestTimeout(t *testing.T) {
	synctest.Test(t, func(t *testing.T) {
		start := time.Now()
		ctx, cancel := context.WithTimeout(t.Context(), time.Hour)
		defer cancel()
		time.Sleep(59 * time.Minute)
		synctest.Wait()
		if err := ctx.Err(); err != nil {
			t.Fatalf("59分で期限切れ: %v", err)
		}
		time.Sleep(time.Minute)
		synctest.Wait()
		if ctx.Err() != context.DeadlineExceeded {
			t.Fatalf("60分で期限切れにならない: %v", ctx.Err())
		}
		t.Logf("仮想時計の経過: %v", time.Since(start))
	})
}
$ go test -v -run Timeout .
    sync_test.go:25: 仮想時計の経過: 1h0m0s
--- PASS: TestTimeout (0.00s)

テスト内の時計は1時間進み、実時間は0.00秒です。1.24の実験版で使っていたsynctest.Runは、1.25ではGOEXPERIMENT=synctestを付けたときだけ残っています。付けずにビルドするとundefined: synctest.Runになり、go1.26.5ではGOEXPERIMENT=synctest自体がunknown GOEXPERIMENT synctestで拒否されました。1.24の実験版で書いたテストは、1.25へ上げる時点でsynctest.Testへ書き換えるのが手戻りの少ない順序です。

T.Attr・Outputと-jsonのattrアクション

T.Attr・B.Attr・F.Attrは、テストにキーと値の属性を付けてログへ出力します。チケット番号やテスト対象の環境名など、テスト名だけでは分からない情報を結果に残すときに使います。

func TestAttr(t *testing.T) {
	t.Attr("issue", "GH-1234")
	fmt.Fprintln(t.Output(), "Outputへの書き込み")
	t.Log("Logへの書き込み")
}
$ go test -v -run Attr .
=== RUN   TestAttr
=== ATTR  TestAttr issue GH-1234
    Outputへの書き込み
    attr_test.go:11: Logへの書き込み

$ go test -json -run Attr . | grep attr
{"Action":"attr","Package":"feat","Test":"TestAttr","Key":"issue","Value":"GH-1234"}

-jsonでは"Action":"attr"の独立した行になるため、CIのパーサーはKeyとValueを直接読めます(出力のTimeは省略)。新しいOutputメソッドはt.Logと同じ字下げで書き込みますが、ファイル名と行番号は付きません。このほか、並列テストの実行中にtesting.AllocsPerRunを呼ぶとpanicするようになりました。他のテストの割り当てが混ざって結果が不安定になるのを防ぐためです。

sync.WaitGroup.Goとgo vetの新しい検査

sync.WaitGroup.Goは、wg.Add(1)・go func()・defer wg.Done()の3行を1回の呼び出しにまとめます。渡す関数はpanicしてはならず、WaitGroupが空の場合はWaitより先にGoを呼ぶ必要があります。

var wg sync.WaitGroup
var n atomic.Int64
for i := range 100 {
	wg.Go(func() { n.Add(int64(i)) })
}
wg.Wait()

あわせてgo vetに2つのアナライザーが入りました。waitgroupはゴルーチンの中でwg.Addを呼ぶ誤り(Waitが先に戻る競合の原因)を、hostportはIPv6で動かないfmt.Sprintf("%s:%d", host, port)形式のアドレス組み立てを報告します。

$ go vet ./vetwg
vetwg/main.go:12:10: WaitGroup.Add called from inside new goroutine

$ go vet ./vethp
vethp/main.go:10:43: address format "%s:%d" does not work with IPv6

hostportの指摘にはnet.JoinHostPortで直します。注意したいのは、go行がgo 1.24のモジュールでwg.Goを使った場合です。go1.25.14ではgo buildは通りましたが、go vetがsync.Go requires go1.25 or later (module is go1.24)を報告しました。新しいAPIを使うならgo行も1.25へ上げてください。排他制御全般の使い分けはsync.MutexとRWMutexの違いと使い分け、ゴルーチンの基本はゴルーチン(Goroutine)とはで扱っています。

実験機能のその後:Green Tea GCとencoding/json/v2

1.25でGOEXPERIMENTとして入った2つの機能は、その後の版で既定・正式に変わっています。1.25のまま試す場合と、1.26以降で使う場合では切り替え方が逆になる点に注意してください。

機能 Go 1.25 Go 1.26 Go 1.27
Green Tea GC greenteagcで有効化 既定(nogreenteagcで無効化) 既定
encoding/json/v2 jsonv2で有効化 実験のまま 正式(nojsonv2で旧実装)
synctest旧API synctestで残存 GOEXPERIMENT自体が不明 同左

Green Tea GCの処理負荷削減と後続版での既定化

小さいオブジェクトのマークとスキャンを、メモリの局所性とCPUのスケーラビリティを高める設計に変えたGCです。1.25のリリースノートは、GCを多用する実プログラムでGCのオーバーヘッドが10〜40%減ると見込んでいます。1.26で既定になり、GOEXPERIMENT=nogreenteagcで無効にできます。Go 1.26のリリースノートは「この無効化設定は1.27で削除される見込み」としていましたが、go1.27.3でもGOEXPERIMENT=nogreenteagc付きのビルドは通り、go version -mにはGOEXPERIMENT=nogreenteagcが記録されました(2026年10月31日確認)。1.25で本番に試験導入するより、既定になった1.26以降へ上げて評価するほうが手戻りがありません。

encoding/json/v2の入出力の違いとGo 1.27での正式化

1.25ではGOEXPERIMENT=jsonv2を付けたときだけencoding/json/v2とencoding/json/jsontextが使えます。付けずにimportするとbuild constraints exclude all Go filesでビルドできません。v1とv2で同じ入力を処理すると、次の違いが出ました(go1.25.14、go1.27.1とも同じ結果)。

入力・操作 v1(encoding/json) v2
nilスライスを出力 "tags":null "tags":[]
{"NAME":"b"}を読む Nameにbが入る 空のまま
重複キーを読む エラーなし duplicate object member name

v2はキー名の大文字小文字を区別し、重複キーをエラーにします。外部APIの大文字キーをv1の緩い照合に頼って読んでいるコードは、v2へ移すと値が空になります。1.25のjsonv2実験ではv1のencoding/jsonも新実装の上で動きますが、リリースノートは「エンコード・デコードの結果は変わらず、エラー文言だけが変わりうる」としています。v2は1.27で正式版になったため、v2のAPIで書き直すなら1.27以降を前提にするのが筋です。

ツールチェーンの追加:go.mod ignore・DWARF5・ASan

go.modのignoreによるパッケージ探索からの除外

go.modにignoreを書くと、./...やallのパターン照合からそのディレクトリを外せます。フロントエンドと同居するリポジトリで、node_modules内の.goファイルがビルドを壊す問題への対処です。

module ign

go 1.25

ignore ./node_modules
$ go build ./...        # ignore なし
node_modules/x/bad.go:3:1: syntax error: non-declaration statement outside function body

$ go build ./...        # ignore あり
(成功・go list ./... は ign のみ)

$ GOTOOLCHAIN=go1.24.13 go build ./...
go: errors parsing go.mod:
go.mod:5: unknown directive: ignore

無視したディレクトリもモジュールのzipには含まれます。go1.24.13はignore行のあるgo.modを読めずに止まるため、チームやCIに1.24以前のツールチェーンが残っている間は書けません。

DWARF 5によるデバッグ情報のサイズ削減

1.25のコンパイラとリンカはデバッグ情報をDWARF 5で出力します。net/httpで1ハンドラだけのサーバーをlinux/amd64向けにビルドし、.debug_セクションの合計を比べました。

ビルド .debug_合計 ファイルサイズ
go1.24.13 7,730,472バイト 8,193,887バイト
go1.25.14 4,739,267バイト 8,102,359バイト
go1.25.14 nodwarf5 7,895,278バイト 8,310,588バイト

ELFの各デバッグセクションの展開後サイズを合計すると約39%減りましたが、圧縮されたデバッグ情報を含むファイル全体では約1%の差にとどまります。デバッガやプロファイラがDWARF 5を読めない場合はGOEXPERIMENT=nodwarf5で旧形式に戻せますが、リリースノートはこの退避手段を将来削除しうるとしています。

go build -asanのリーク検出と小さなgoコマンド変更

go build -asanは、プログラム終了時のメモリリーク検出が既定になりました。Cで確保され、CからもGoからも参照されずに解放されていないメモリがあるとエラーを報告します。cgoのリークを許容して既存のCIを通す場合は、実行時にASAN_OPTIONS=detect_leaks=0を設定します。ASan自体の読み方はSegmentation faultの原因と調べ方で説明しています。そのほかのgoコマンドの変更は次のとおりです。

  • go doc -http:指定した対象のドキュメントサーバーを起動し、ブラウザで開く
  • go version -m -json:バイナリに埋め込まれたビルド情報をJSONで出力
  • workパターン:ワークスペース内のモジュールのパッケージすべてに一致
  • go.modのgo行を更新してもtoolchain行を自動で足さなくなった
  • ビルドやテストで使わないツールは同梱せず、go toolが必要時にビルド

標準ライブラリの注目変更

net/http.CrossOriginProtectionによるCSRF対策

http.CrossOriginProtectionは、トークンやCookieを使わずにCSRFを防ぐハンドラーです。ブラウザが付けるSec-Fetch-SiteヘッダーとOriginヘッダーを見て、安全でないメソッドのクロスオリジン要求を拒否します。httptestで要求を組み立てて確かめた結果です。

要求 応答
POST・Sec-Fetch-Site: cross-site 403
POST・Sec-Fetch-Site: same-origin 200
GET・Sec-Fetch-Site: cross-site 200
POST・ヘッダーなし(curl等) 200
POST・Originのみ別ホスト 403
POST・cross-site+AddTrustedOriginで登録済み 200

ヘッダーを付けないcurlやサーバー間通信の要求は通ります。この設計では、ヘッダーのない要求を同一オリジンまたはブラウザ以外からの要求として扱います。ただし、常に許可されるGET・HEAD・OPTIONSでデータ更新などの状態変更を行わないことが前提です。逆にいえば、API認証の代わりにはなりません。外部の決済画面などからのPOSTを受ける場合は、AddTrustedOriginでそのオリジンを登録します。

runtime/trace.FlightRecorderによる直前の実行トレースの保存

実行トレースをメモリ上のリングバッファへ記録し続け、異常を検知した時点で直前の数秒分だけをファイルへ書き出す仕組みです。トレースを常時ファイルへ保存するI/Oを避けながら、まれな遅延の原因を追えます。ただし、実行中のイベント記録とメモリ保持のコストは発生します。

fr := trace.NewFlightRecorder(trace.FlightRecorderConfig{
	MinAge:   5 * time.Second,
	MaxBytes: 4 << 20,
})
if err := fr.Start(); err != nil {
	log.Fatal(err)
}
defer fr.Stop()

// 遅い要求などを検知したら
f, err := os.Create("slow.trace")
if err != nil {
	log.Print(err)
	return
}
defer f.Close()
if _, err := fr.WriteTo(f); err != nil {
	log.Print(err)
}

MinAgeは保持する期間の下限、MaxBytesは保持ウィンドウの容量上限の目安で、出力ファイルのサイズやメモリ使用量の厳密な上限を保証しません。両方を指定するとMaxBytesが優先されます(go doc runtime/trace.FlightRecorderConfig)。書き出したファイルはgo tool trace slow.traceで開けます。

os.Root・reflect・暗号ライブラリなどのAPI追加と性能変更

  • os.Root:ReadFile・WriteFile・MkdirAll・RemoveAll・Renameなど12メソッドを追加
  • reflect.TypeAssert:Value.Interfaceを経由する型アサーションで生じる不要なメモリ割り当てを回避
  • log/slog:GroupAttrsとRecord.Sourceを追加
  • crypto/rsa:鍵生成が3倍速く、crypto/ecdsa・ed25519はFIPS 140-3モードでの署名が4倍速く
  • unique:不要になった値の回収が早まり、Makeを多用したときのメモリ膨張が起きにくくなった

一方で、AVX2を持たないamd64ではSHA-1・SHA-256・SHA-512が遅くなりました。リリースノートは「2015年以降のサーバー向けプロセッサはほぼAVX2対応」としていますが、古い仮想CPU定義で動かしている環境では計測し直す価値があります。

よくある質問

Go 1.25はいつリリースされ、いつまでサポートされますか?

2025年8月12日にリリースされ、2026年8月19日のGo 1.27公開でサポートが終わりました。同じ日に出たgo1.25.14が最後のパッチで、2026年10月8日と19日に1.26系・1.27系へ出たセキュリティ修正は1.25系には出ていません。

Go 1.25で言語仕様は変わりましたか?

プログラムに影響する言語の変更はありません。言語仕様書から「コア型(core type)」という概念を削除し、ジェネリクスの規則を個別の説明文に書き換えましたが、コンパイルできるコードの範囲は変わりません。

ツールチェーンを1.25にすれば新機能は全部有効になりますか?

なりません。コンテナ対応のGOMAXPROCSやTLS 1.2のSHA-1署名拒否は、go.modのgo行が1.25以上のときに有効になります。一方、nilチェックの修正はgo行に関係なく、1.25のコンパイラでビルドした時点で効きます。

Go 1.25で追加されたencoding/json/v2はそのまま使えますか?

1.25ではビルド時にGOEXPERIMENT=jsonv2が必要な実験機能です。正式版になったのはGo 1.27なので、本番で使うなら1.27以降を前提にしてください。

今Go 1.25を使っている場合、どの版へ上げるべきですか?

1.25はサポートが終わっているため、1.26か1.27へ上げます。2026年10月31日時点の最新パッチはgo1.27.3とgo1.26.10です。Green Tea GCが既定になる1.26、json/v2が正式版になる1.27と、版ごとに既定の挙動が変わります。最新の安定版と更新手順はGo 1.27の新機能・変更点まとめで確認してください。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

この記事は以下の記事からリンクされています

資料請求

RELATED POSTS 関連記事

目次