Repository: scionproto/scion
Pull request #3801 (2020-06-24 11:01:39)

toml: switch to better maintained library
https://github.com/BurntSushi/toml is not actively developed anymore.
https://github.com/pelletier/go-toml/ has a lot of active contributors.
The new lib supports all use cases we need, thanks to contributions of @Oncilla.
It handles encoding of empty fields and substructs better,
i.e. correctly omits them in the output.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/scionproto/scion/3801)
<!-- Reviewable:end -->



Patch:
diff --git a/WORKSPACE b/WORKSPACE
index 7e35c7621..2d9db0814 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -35,7 +35,15 @@ http_archive(
     ],
 )
 
-load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
+load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
+load("//:tool_deps.bzl", "tool_deps")
+
+tool_deps()
+
+# gazelle:repository_macro go_deps.bzl%go_deps
+load("//:go_deps.bzl", "go_deps")
+
+go_deps()
 
 gazelle_dependencies()
 
@@ -249,12 +257,3 @@ http_archive(
     strip_prefix = "buildtools-master",
     url = "https://github.com/bazelbuild/buildtools/archive/2.2.1.zip",
 )
-
-load("//:tool_deps.bzl", "tool_deps")
-
-tool_deps()
-
-# gazelle:repository_macro go_deps.bzl%go_deps
-load("//:go_deps.bzl", "go_deps")
-
-go_deps()
diff --git a/go.mod b/go.mod
index 3ec17d09a..812cd4ffc 100644
--- a/go.mod
+++ b/go.mod
@@ -1,7 +1,6 @@
 module github.com/scionproto/scion
 
 require (
-	github.com/BurntSushi/toml v0.3.1
 	github.com/antlr/antlr4 v0.0.0-20181218183524-be58ebffde8e
 	github.com/buildkite/go-buildkite v2.2.1-0.20190413010238-568b6651b687+incompatible
 	github.com/cenkalti/backoff v2.2.1+incompatible // indirect
@@ -21,6 +20,7 @@ require (
 	github.com/mattn/go-sqlite3 v1.9.1-0.20180719091609-b3511bfdd742
 	github.com/opentracing/opentracing-go v1.1.0
 	github.com/patrickmn/go-cache v2.1.1-0.20180815053127-5633e0862627+incompatible
+	github.com/pelletier/go-toml v1.8.0
 	github.com/pkg/errors v0.8.2-0.20190227000051-27936f6d90f9 // indirect
 	github.com/prometheus/client_golang v1.1.0
 	github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 // indirect
@@ -40,7 +40,7 @@ require (
 	golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c
 	gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3
 	gopkg.in/restruct.v1 v1.0.0-20151213023948-80ede2e57cc2
-	gopkg.in/yaml.v2 v2.2.4
+	gopkg.in/yaml.v2 v2.3.0
 	zombiezen.com/go/capnproto2 v0.0.0-20190813022230-ddfb9bb855fa
 )
 
diff --git a/go.sum b/go.sum
index 0148e201e..9a2930f92 100644
--- a/go.sum
+++ b/go.sum
@@ -181,7 +181,10 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt
 github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
 github.com/patrickmn/go-cache v2.1.1-0.20180815053127-5633e0862627+incompatible h1:MUIwjEiAMYk8zkXXUQeb5itrXF+HpS2pfxNsA2a7AiY=
 github.com/patrickmn/go-cache v2.1.1-0.20180815053127-5633e0862627+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
+github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw=
+github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
 github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
 github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -420,6 +423,8 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
 honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/go/border/BUILD.bazel b/go/border/BUILD.bazel
index d8a958d5b..20ade65cf 100644
--- a/go/border/BUILD.bazel
+++ b/go/border/BUILD.bazel
@@ -26,6 +26,7 @@ go_library(
         "//go/lib/addr:go_default_library",
         "//go/lib/assert:go_default_library",
         "//go/lib/common:go_default_library",
+        "//go/lib/config:go_default_library",
         "//go/lib/env:go_default_library",
         "//go/lib/fatal:go_default_library",
         "//go/lib/infra/modules/itopo:go_default_library",
@@ -39,7 +40,7 @@ go_library(
         "//go/lib/topology:go_default_library",
         "//go/lib/underlay/conn:go_default_library",
         "//go/proto:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_syndtr_gocapability//capability:go_default_library",
         "@org_golang_x_net//ipv4:go_default_library",
     ],
diff --git a/go/border/brconf/BUILD.bazel b/go/border/brconf/BUILD.bazel
index ce6807006..533f0df55 100644
--- a/go/border/brconf/BUILD.bazel
+++ b/go/border/brconf/BUILD.bazel
@@ -29,7 +29,7 @@ go_test(
     deps = [
         "//go/lib/env/envtest:go_default_library",
         "//go/lib/log/logtest:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
     ],
 )
diff --git a/go/border/main.go b/go/border/main.go
index c48bec771..67abd7889 100644
--- a/go/border/main.go
+++ b/go/border/main.go
@@ -28,12 +28,13 @@ import (
 	"os"
 	"os/user"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 
 	"github.com/scionproto/scion/go/border/brconf"
 	"github.com/scionproto/scion/go/border/ifstate"
 	"github.com/scionproto/scion/go/lib/assert"
 	"github.com/scionproto/scion/go/lib/common"
+	libconfig "github.com/scionproto/scion/go/lib/config"
 	"github.com/scionproto/scion/go/lib/env"
 	"github.com/scionproto/scion/go/lib/fatal"
 	"github.com/scionproto/scion/go/lib/infra/modules/itopo"
@@ -102,13 +103,9 @@ func realMain() int {
 }
 
 func setupBasic() error {
-	md, err := toml.DecodeFile(env.ConfigFile(), &cfg)
-	if err != nil {
+	if err := libconfig.LoadFile(env.ConfigFile(), &cfg); err != nil {
 		return serrors.WrapStr("Failed to load config", err, "file", env.ConfigFile())
 	}
-	if len(md.Undecoded()) > 0 {
-		return serrors.New("Failed to load config: undecoded keys", "undecoded", md.Undecoded())
-	}
 	cfg.InitDefaults()
 	if err := log.Setup(cfg.Logging); err != nil {
 		return serrors.WrapStr("Failed to initialize logging", err)
@@ -149,7 +146,7 @@ func checkPerms() error {
 func configHandler(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "text/plain")
 	var buf bytes.Buffer
-	toml.NewEncoder(&buf).Encode(cfg)
+	toml.NewEncoder(&buf).Order(toml.OrderPreserve).Encode(cfg)
 	fmt.Fprint(w, buf.String())
 }
 
diff --git a/go/cs/BUILD.bazel b/go/cs/BUILD.bazel
index b63fb1180..575205d5c 100644
--- a/go/cs/BUILD.bazel
+++ b/go/cs/BUILD.bazel
@@ -7,12 +7,12 @@ go_library(
     importpath = "github.com/scionproto/scion/go/cs",
     visibility = ["//visibility:private"],
     deps = [
+        "//go/lib/config:go_default_library",
         "//go/lib/env:go_default_library",
         "//go/lib/fatal:go_default_library",
         "//go/lib/log:go_default_library",
         "//go/lib/serrors:go_default_library",
         "//go/pkg/cs:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
     ],
 )
 
diff --git a/go/cs/config/BUILD.bazel b/go/cs/config/BUILD.bazel
index 59ad1cd40..5ba24bbb9 100644
--- a/go/cs/config/BUILD.bazel
+++ b/go/cs/config/BUILD.bazel
@@ -35,7 +35,7 @@ go_test(
         "//go/lib/pathstorage/pathstoragetest:go_default_library",
         "//go/lib/truststorage/truststoragetest:go_default_library",
         "//go/lib/util:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
     ],
 )
diff --git a/go/cs/main.go b/go/cs/main.go
index 665c1e34d..c4a78b69f 100644
--- a/go/cs/main.go
+++ b/go/cs/main.go
@@ -18,8 +18,7 @@ import (
 	"flag"
 	"os"
 
-	"github.com/BurntSushi/toml"
-
+	"github.com/scionproto/scion/go/lib/config"
 	"github.com/scionproto/scion/go/lib/env"
 	"github.com/scionproto/scion/go/lib/fatal"
 	"github.com/scionproto/scion/go/lib/log"
@@ -55,7 +54,7 @@ func realMain() int {
 // on environment variables, command line arguments and the configuration
 // files.
 func InitConfiguration() error {
-	if _, err := toml.DecodeFile(env.ConfigFile(), &cs.Cfg); err != nil {
+	if err := config.LoadFile(env.ConfigFile(), &cs.Cfg); err != nil {
 		return serrors.WrapStr("failed to load config", err, "file", env.ConfigFile())
 	}
 	cs.Cfg.InitDefaults()
diff --git a/go/dispatcher/BUILD.bazel b/go/dispatcher/BUILD.bazel
index df22175fa..28eec7d69 100644
--- a/go/dispatcher/BUILD.bazel
+++ b/go/dispatcher/BUILD.bazel
@@ -10,13 +10,14 @@ go_library(
         "//go/dispatcher/config:go_default_library",
         "//go/dispatcher/network:go_default_library",
         "//go/lib/common:go_default_library",
+        "//go/lib/config:go_default_library",
         "//go/lib/env:go_default_library",
         "//go/lib/fatal:go_default_library",
         "//go/lib/log:go_default_library",
         "//go/lib/prom:go_default_library",
         "//go/lib/serrors:go_default_library",
         "//go/lib/util:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
     ],
 )
 
diff --git a/go/dispatcher/config/BUILD.bazel b/go/dispatcher/config/BUILD.bazel
index 03d28deab..0359b7480 100644
--- a/go/dispatcher/config/BUILD.bazel
+++ b/go/dispatcher/config/BUILD.bazel
@@ -28,7 +28,7 @@ go_test(
         "//go/lib/log/logtest:go_default_library",
         "//go/lib/sock/reliable:go_default_library",
         "//go/lib/topology:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
     ],
 )
diff --git a/go/dispatcher/main.go b/go/dispatcher/main.go
index 53ff37653..280dd8036 100644
--- a/go/dispatcher/main.go
+++ b/go/dispatcher/main.go
@@ -24,11 +24,12 @@ import (
 	"os"
 	"os/user"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 
 	"github.com/scionproto/scion/go/dispatcher/config"
 	"github.com/scionproto/scion/go/dispatcher/network"
 	"github.com/scionproto/scion/go/lib/common"
+	libconfig "github.com/scionproto/scion/go/lib/config"
 	"github.com/scionproto/scion/go/lib/env"
 	"github.com/scionproto/scion/go/lib/fatal"
 	"github.com/scionproto/scion/go/lib/log"
@@ -112,13 +113,9 @@ func realMain() int {
 }
 
 func setupBasic() error {
-	md, err := toml.DecodeFile(env.ConfigFile(), &cfg)
-	if err != nil {
+	if err := libconfig.LoadFile(env.ConfigFile(), &cfg); err != nil {
 		return serrors.WrapStr("failed to load config", err, "file", env.ConfigFile())
 	}
-	if len(md.Undecoded()) > 0 {
-		return serrors.New("failed to load config: undecoded keys", "undecoded", md.Undecoded())
-	}
 	cfg.InitDefaults()
 	if err := log.Setup(cfg.Logging); err != nil {
 		return serrors.WrapStr("failed to initialize logging", err)
@@ -178,6 +175,6 @@ func checkPerms() error {
 func configHandler(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "text/plain")
 	var buf bytes.Buffer
-	toml.NewEncoder(&buf).Encode(cfg)
+	toml.NewEncoder(&buf).Order(toml.OrderPreserve).Encode(cfg)
 	fmt.Fprint(w, buf.String())
 }
diff --git a/go/lib/config/BUILD.bazel b/go/lib/config/BUILD.bazel
index 94f1c91c5..2ea87e26b 100644
--- a/go/lib/config/BUILD.bazel
+++ b/go/lib/config/BUILD.bazel
@@ -10,7 +10,6 @@ go_library(
     visibility = ["//visibility:public"],
     deps = [
         "//go/lib/common:go_default_library",
-        "//go/lib/serrors:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
     ],
 )
diff --git a/go/lib/config/config.go b/go/lib/config/config.go
index a483a8e53..5a689a1b0 100644
--- a/go/lib/config/config.go
+++ b/go/lib/config/config.go
@@ -45,14 +45,14 @@
 package config
 
 import (
+	"bytes"
 	"fmt"
 	"io"
 	"io/ioutil"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 
 	"github.com/scionproto/scion/go/lib/common"
-	"github.com/scionproto/scion/go/lib/serrors"
 )
 
 const ID = "id"
@@ -162,12 +162,8 @@ func LoadFile(file string, cfg interface{}) error {
 	if err != nil {
 		return err
 	}
-	m, err := toml.Decode(string(raw), cfg)
-	if err != nil {
+	if err := toml.NewDecoder(bytes.NewReader(raw)).Strict(true).Decode(cfg); err != nil {
 		return err
 	}
-	if len(m.Undecoded()) > 0 {
-		return serrors.New("undecoded keys in configuration", "keys", m.Undecoded())
-	}
 	return nil
 }
diff --git a/go/lib/log/BUILD.bazel b/go/lib/log/BUILD.bazel
index b72096d41..e8694306b 100644
--- a/go/lib/log/BUILD.bazel
+++ b/go/lib/log/BUILD.bazel
@@ -40,7 +40,7 @@ go_test(
         "//go/lib/config:go_default_library",
         "//go/lib/log/logtest:go_default_library",
         "//go/lib/xtest:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
     ],
 )
diff --git a/go/lib/util/BUILD.bazel b/go/lib/util/BUILD.bazel
index 17f2459e0..3ae30df31 100644
--- a/go/lib/util/BUILD.bazel
+++ b/go/lib/util/BUILD.bazel
@@ -23,7 +23,6 @@ go_library(
     deps = [
         "//go/lib/addr:go_default_library",
         "//go/lib/common:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
         "@in_gopkg_yaml_v2//:go_default_library",
     ],
 )
diff --git a/go/lib/util/duration_wrap.go b/go/lib/util/duration_wrap.go
index 1bfdad4ac..f6cdbcef7 100644
--- a/go/lib/util/duration_wrap.go
+++ b/go/lib/util/duration_wrap.go
@@ -15,14 +15,13 @@
 package util
 
 import (
+	"encoding"
 	"flag"
 	"time"
-
-	"github.com/BurntSushi/toml"
 )
 
-var _ (toml.TextUnmarshaler) = (*DurWrap)(nil)
-var _ (toml.TextMarshaler) = DurWrap{}
+var _ (encoding.TextUnmarshaler) = (*DurWrap)(nil)
+var _ (encoding.TextMarshaler) = DurWrap{}
 var _ (flag.Value) = (*DurWrap)(nil)
 
 // DurWrap is a wrapper to enable marshalling and unmarshalling of durations
diff --git a/go/lib/util/file_mode.go b/go/lib/util/file_mode.go
index e08243f17..140ff597a 100644
--- a/go/lib/util/file_mode.go
+++ b/go/lib/util/file_mode.go
@@ -15,13 +15,12 @@
 package util
 
 import (
+	"encoding"
 	"os"
 	"strconv"
-
-	"github.com/BurntSushi/toml"
 )
 
-var _ (toml.TextUnmarshaler) = (*FileMode)(nil)
+var _ (encoding.TextUnmarshaler) = (*FileMode)(nil)
 
 type FileMode os.FileMode
 
diff --git a/go/pkg/cs/BUILD.bazel b/go/pkg/cs/BUILD.bazel
index 763ccf094..bcc53ffc5 100644
--- a/go/pkg/cs/BUILD.bazel
+++ b/go/pkg/cs/BUILD.bazel
@@ -53,8 +53,8 @@ go_library(
         "//go/pkg/trust/metrics:go_default_library",
         "//go/pkg/trust/renewal:go_default_library",
         "//go/proto:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
         "@com_github_opentracing_opentracing_go//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_prometheus_client_golang//prometheus:go_default_library",
         "@in_gopkg_yaml_v2//:go_default_library",
     ],
diff --git a/go/pkg/cs/main.go b/go/pkg/cs/main.go
index 7c60392e8..ca0e44787 100644
--- a/go/pkg/cs/main.go
+++ b/go/pkg/cs/main.go
@@ -29,8 +29,8 @@ import (
 	"sync"
 	"time"
 
-	"github.com/BurntSushi/toml"
 	"github.com/opentracing/opentracing-go"
+	"github.com/pelletier/go-toml"
 	"github.com/prometheus/client_golang/prometheus"
 	"gopkg.in/yaml.v2"
 
@@ -115,8 +115,7 @@ func (app *App) runConfigLoader() error {
 	if app.ConfigLoader != nil {
 		return app.ConfigLoader()
 	}
-	_, err := toml.DecodeFile(env.ConfigFile(), &Cfg)
-	return err
+	return libconfig.LoadFile(env.ConfigFile(), &Cfg)
 }
 
 func (app *App) runPathDBConstructor(
@@ -994,7 +993,7 @@ func (h *chainedHandler) Handle(r *infra.Request) *infra.HandlerResult {
 func configHandler(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "text/plain")
 	var buf bytes.Buffer
-	toml.NewEncoder(&buf).Encode(Cfg)
+	toml.NewEncoder(&buf).Order(toml.OrderPreserve).Encode(Cfg)
 	fmt.Fprint(w, buf.String())
 }
 
diff --git a/go/pkg/sciond/BUILD.bazel b/go/pkg/sciond/BUILD.bazel
index d207dd559..7f99237af 100644
--- a/go/pkg/sciond/BUILD.bazel
+++ b/go/pkg/sciond/BUILD.bazel
@@ -19,7 +19,7 @@ go_library(
         "//go/pkg/trust:go_default_library",
         "//go/pkg/trust/compat:go_default_library",
         "//go/proto:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
         "@com_github_opentracing_opentracing_go//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
     ],
 )
diff --git a/go/pkg/sciond/config/BUILD.bazel b/go/pkg/sciond/config/BUILD.bazel
index c368634b9..2119de2e6 100644
--- a/go/pkg/sciond/config/BUILD.bazel
+++ b/go/pkg/sciond/config/BUILD.bazel
@@ -30,7 +30,7 @@ go_test(
         "//go/lib/pathstorage/pathstoragetest:go_default_library",
         "//go/lib/sciond:go_default_library",
         "//go/lib/truststorage/truststoragetest:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
     ],
 )
diff --git a/go/pkg/sciond/sciond.go b/go/pkg/sciond/sciond.go
index 671a220d8..7da5911be 100644
--- a/go/pkg/sciond/sciond.go
+++ b/go/pkg/sciond/sciond.go
@@ -22,8 +22,8 @@ import (
 	"net/http"
 	"path/filepath"
 
-	"github.com/BurntSushi/toml"
 	"github.com/opentracing/opentracing-go"
+	"github.com/pelletier/go-toml"
 
 	"github.com/scionproto/scion/go/lib/env"
 	"github.com/scionproto/scion/go/lib/infra/messenger/tcp"
@@ -118,7 +118,7 @@ func StartHTTPEndpoints(cfg interface{}, metrics env.Metrics) {
 	http.HandleFunc("/config", func(w http.ResponseWriter, r *http.Request) {
 		w.Header().Set("Content-Type", "text/plain")
 		var buf bytes.Buffer
-		toml.NewEncoder(&buf).Encode(cfg)
+		toml.NewEncoder(&buf).Order(toml.OrderPreserve).Encode(cfg)
 		fmt.Fprint(w, buf.String())
 	})
 	http.HandleFunc("/info", env.InfoHandler)
diff --git a/go/scion-pki/conf/BUILD.bazel b/go/scion-pki/conf/BUILD.bazel
index 373301496..e4717ed8b 100644
--- a/go/scion-pki/conf/BUILD.bazel
+++ b/go/scion-pki/conf/BUILD.bazel
@@ -16,11 +16,11 @@ go_library(
     visibility = ["//visibility:public"],
     deps = [
         "//go/lib/addr:go_default_library",
+        "//go/lib/config:go_default_library",
         "//go/lib/scrypto:go_default_library",
         "//go/lib/scrypto/cppki:go_default_library",
         "//go/lib/serrors:go_default_library",
         "//go/lib/util:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
     ],
 )
 
diff --git a/go/scion-pki/conf/trc.go b/go/scion-pki/conf/trc.go
index 93decc3f6..01f67b185 100644
--- a/go/scion-pki/conf/trc.go
+++ b/go/scion-pki/conf/trc.go
@@ -19,9 +19,8 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/BurntSushi/toml"
-
 	"github.com/scionproto/scion/go/lib/addr"
+	"github.com/scionproto/scion/go/lib/config"
 	"github.com/scionproto/scion/go/lib/scrypto"
 	"github.com/scionproto/scion/go/lib/scrypto/cppki"
 	"github.com/scionproto/scion/go/lib/serrors"
@@ -49,14 +48,10 @@ type TRC struct {
 // LoadTRC loads the TRC configuration from the provided file. The contents are already validated.
 func LoadTRC(file string) (TRC, error) {
 	var cfg TRC
-	meta, err := toml.DecodeFile(file, &cfg)
-	if err != nil {
+	if err := config.LoadFile(file, &cfg); err != nil {
 		return TRC{}, serrors.WrapStr("unable to load TRC config from file", err, "file", file)
 	}
 	cfg.relPath = filepath.Dir(file)
-	if len(meta.Undecoded()) > 0 {
-		return TRC{}, serrors.New("unknown configuration values", "keys", meta.Undecoded)
-	}
 	return cfg, nil
 }
 
diff --git a/go/sig/BUILD.bazel b/go/sig/BUILD.bazel
index 2acafbc28..76983ead3 100644
--- a/go/sig/BUILD.bazel
+++ b/go/sig/BUILD.bazel
@@ -8,6 +8,7 @@ go_library(
     visibility = ["//visibility:private"],
     deps = [
         "//go/lib/common:go_default_library",
+        "//go/lib/config:go_default_library",
         "//go/lib/env:go_default_library",
         "//go/lib/fatal:go_default_library",
         "//go/lib/log:go_default_library",
@@ -22,7 +23,7 @@ go_library(
         "//go/sig/internal/sigcmn:go_default_library",
         "//go/sig/internal/sigconfig:go_default_library",
         "//go/sig/internal/xnet:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_syndtr_gocapability//capability:go_default_library",
     ],
 )
diff --git a/go/sig/internal/sigconfig/BUILD.bazel b/go/sig/internal/sigconfig/BUILD.bazel
index 2de11ec16..94a22d700 100644
--- a/go/sig/internal/sigconfig/BUILD.bazel
+++ b/go/sig/internal/sigconfig/BUILD.bazel
@@ -25,7 +25,7 @@ go_test(
         "//go/lib/env/envtest:go_default_library",
         "//go/lib/log/logtest:go_default_library",
         "//go/lib/xtest:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
     ],
 )
diff --git a/go/sig/main.go b/go/sig/main.go
index f5b1fb5d3..6c24fd39f 100644
--- a/go/sig/main.go
+++ b/go/sig/main.go
@@ -26,10 +26,11 @@ import (
 	"os/user"
 	"sync/atomic"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 	"github.com/syndtr/gocapability/capability"
 
 	"github.com/scionproto/scion/go/lib/common"
+	libconfig "github.com/scionproto/scion/go/lib/config"
 	"github.com/scionproto/scion/go/lib/env"
 	"github.com/scionproto/scion/go/lib/fatal"
 	"github.com/scionproto/scion/go/lib/log"
@@ -120,13 +121,9 @@ func realMain() int {
 // setupBasic loads the config from file and initializes logging.
 func setupBasic() error {
 	// Load and initialize config.
-	md, err := toml.DecodeFile(env.ConfigFile(), &cfg)
-	if err != nil {
+	if err := libconfig.LoadFile(env.ConfigFile(), &cfg); err != nil {
 		return serrors.WrapStr("Failed to load config", err, "file", env.ConfigFile())
 	}
-	if len(md.Undecoded()) > 0 {
-		return serrors.New("Failed to load config: undecoded keys", "undecoded", md.Undecoded())
-	}
 	cfg.InitDefaults()
 	if err := log.Setup(cfg.Logging); err != nil {
 		return serrors.WrapStr("Failed to initialize logging", err)
@@ -217,6 +214,6 @@ func loadConfig(path string) bool {
 func configHandler(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "text/plain")
 	var buf bytes.Buffer
-	toml.NewEncoder(&buf).Encode(cfg)
+	toml.NewEncoder(&buf).Order(toml.OrderPreserve).Encode(cfg)
 	fmt.Fprint(w, buf.String())
 }
diff --git a/go_deps.bzl b/go_deps.bzl
index dac8b27bc..cec2c4507 100644
--- a/go_deps.bzl
+++ b/go_deps.bzl
@@ -629,8 +629,8 @@ def go_deps():
     go_repository(
         name = "com_github_pelletier_go_toml",
         importpath = "github.com/pelletier/go-toml",
-        sum = "h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=",
-        version = "v1.2.0",
+        sum = "h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw=",
+        version = "v1.8.0",
     )
     go_repository(
         name = "com_github_philhofer_fwd",
@@ -1110,8 +1110,8 @@ def go_deps():
     go_repository(
         name = "in_gopkg_yaml_v2",
         importpath = "gopkg.in/yaml.v2",
-        sum = "h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=",
-        version = "v2.2.4",
+        sum = "h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=",
+        version = "v2.3.0",
     )
     go_repository(
         name = "io_etcd_go_bbolt",
diff --git a/licenses/data/com_github_burntsushi_toml/cmd/tomlv/COPYING b/licenses/data/com_github_burntsushi_toml/cmd/tomlv/COPYING
deleted file mode 100644
index 01b574320..000000000
--- a/licenses/data/com_github_burntsushi_toml/cmd/tomlv/COPYING
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 TOML authors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/licenses/data/com_github_burntsushi_toml/COPYING b/licenses/data/com_github_pelletier_go_toml/LICENSE
similarity index 86%
rename from licenses/data/com_github_burntsushi_toml/COPYING
rename to licenses/data/com_github_pelletier_go_toml/LICENSE
index 01b574320..583bdae62 100644
--- a/licenses/data/com_github_burntsushi_toml/COPYING
+++ b/licenses/data/com_github_pelletier_go_toml/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2013 TOML authors
+Copyright (c) 2013 - 2017 Thomas Pelletier, Eric Anderton
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -9,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.


Test patch:
diff --git a/go/border/brconf/params_test.go b/go/border/brconf/params_test.go
index 7031c2921..45abc611b 100644
--- a/go/border/brconf/params_test.go
+++ b/go/border/brconf/params_test.go
@@ -18,7 +18,7 @@ import (
 	"bytes"
 	"testing"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 	"github.com/stretchr/testify/assert"
 
 	"github.com/scionproto/scion/go/lib/env/envtest"
@@ -31,9 +31,8 @@ func TestConfigSample(t *testing.T) {
 	cfg.Sample(&sample, nil, nil)
 
 	InitTestConfig(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckTestConfig(t, &cfg, idSample)
 }
 
diff --git a/go/cs/beaconstorage/beaconstoragetest/BUILD.bazel b/go/cs/beaconstorage/beaconstoragetest/BUILD.bazel
index 29ca3c091..013b0d852 100644
--- a/go/cs/beaconstorage/beaconstoragetest/BUILD.bazel
+++ b/go/cs/beaconstorage/beaconstoragetest/BUILD.bazel
@@ -20,8 +20,7 @@ go_test(
     deps = [
         "//go/cs/beaconstorage:go_default_library",
         "//go/lib/config:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
-        "@com_github_stretchr_testify//assert:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_stretchr_testify//require:go_default_library",
     ],
 )
diff --git a/go/cs/beaconstorage/beaconstoragetest/config_test.go b/go/cs/beaconstorage/beaconstoragetest/config_test.go
index 49a10cce3..b5aadd145 100644
--- a/go/cs/beaconstorage/beaconstoragetest/config_test.go
+++ b/go/cs/beaconstorage/beaconstoragetest/config_test.go
@@ -18,8 +18,7 @@ import (
 	"bytes"
 	"testing"
 
-	"github.com/BurntSushi/toml"
-	"github.com/stretchr/testify/assert"
+	"github.com/pelletier/go-toml"
 	"github.com/stretchr/testify/require"
 
 	"github.com/scionproto/scion/go/cs/beaconstorage"
@@ -31,8 +30,7 @@ func TestBeaconDBConfSample(t *testing.T) {
 	var cfg beaconstorage.BeaconDBConf
 	cfg.Sample(&sample, nil, map[string]string{config.ID: "test"})
 	InitTestBeaconDBConf(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	require.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckTestBeaconDBConf(t, &cfg, "test")
 }
diff --git a/go/cs/config/config_test.go b/go/cs/config/config_test.go
index bf2dfa7ac..988d1de68 100644
--- a/go/cs/config/config_test.go
+++ b/go/cs/config/config_test.go
@@ -19,7 +19,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 	"github.com/stretchr/testify/assert"
 
 	"github.com/scionproto/scion/go/cs/beaconstorage/beaconstoragetest"
@@ -37,9 +37,8 @@ func TestConfigSample(t *testing.T) {
 	cfg.Sample(&sample, nil, nil)
 
 	InitTestConfig(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckTestConfig(t, &cfg, idSample)
 }
 
diff --git a/go/dispatcher/config/config_test.go b/go/dispatcher/config/config_test.go
index e44761065..1eb0bee48 100644
--- a/go/dispatcher/config/config_test.go
+++ b/go/dispatcher/config/config_test.go
@@ -19,7 +19,7 @@ import (
 	"bytes"
 	"testing"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 	"github.com/stretchr/testify/assert"
 
 	"github.com/scionproto/scion/go/lib/env/envtest"
@@ -34,9 +34,8 @@ func TestConfigSample(t *testing.T) {
 	cfg.Sample(&sample, nil, nil)
 
 	InitTestConfig(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckTestConfig(t, &cfg, idSample)
 }
 
diff --git a/go/lib/env/envtest/BUILD.bazel b/go/lib/env/envtest/BUILD.bazel
index 0b2bba455..555f585f4 100644
--- a/go/lib/env/envtest/BUILD.bazel
+++ b/go/lib/env/envtest/BUILD.bazel
@@ -20,7 +20,7 @@ go_test(
     deps = [
         "//go/lib/config:go_default_library",
         "//go/lib/env:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
     ],
 )
diff --git a/go/lib/env/envtest/config_test.go b/go/lib/env/envtest/config_test.go
index 56bc1a597..a48465887 100644
--- a/go/lib/env/envtest/config_test.go
+++ b/go/lib/env/envtest/config_test.go
@@ -18,7 +18,7 @@ import (
 	"bytes"
 	"testing"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 	"github.com/stretchr/testify/assert"
 
 	"github.com/scionproto/scion/go/lib/config"
@@ -30,9 +30,8 @@ func TestGeneralSample(t *testing.T) {
 	var cfg env.General
 	cfg.Sample(&sample, nil, map[string]string{config.ID: "general"})
 	InitTestGeneral(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckTestGeneral(t, &cfg, "general")
 }
 
@@ -41,9 +40,8 @@ func TestMetricsSample(t *testing.T) {
 	var cfg env.Metrics
 	cfg.Sample(&sample, nil, nil)
 	InitTestMetrics(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckTestMetrics(t, &cfg)
 }
 
@@ -52,9 +50,8 @@ func TestTracingSample(t *testing.T) {
 	var cfg env.Tracing
 	cfg.Sample(&sample, nil, nil)
 	InitTestTracing(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckTestTracing(t, &cfg)
 }
 
@@ -63,8 +60,7 @@ func TestSCIONDClientSample(t *testing.T) {
 	var cfg env.SCIONDClient
 	cfg.Sample(&sample, nil, nil)
 	InitTestSCIOND(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	InitTestSCIOND(&cfg)
 }
diff --git a/go/lib/log/config_test.go b/go/lib/log/config_test.go
index e1b294147..f923f4976 100644
--- a/go/lib/log/config_test.go
+++ b/go/lib/log/config_test.go
@@ -18,7 +18,7 @@ import (
 	"bytes"
 	"testing"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 	"github.com/stretchr/testify/assert"
 
 	"github.com/scionproto/scion/go/lib/config"
@@ -32,8 +32,7 @@ func TestLoggingSample(t *testing.T) {
 	var cfg log.Config
 	cfg.Sample(&sample, nil, map[string]string{config.ID: id})
 	logtest.InitTestLogging(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	logtest.CheckTestLogging(t, &cfg, id)
 }
diff --git a/go/lib/pathstorage/pathstoragetest/BUILD.bazel b/go/lib/pathstorage/pathstoragetest/BUILD.bazel
index 2cf73eeee..ef2b084ca 100644
--- a/go/lib/pathstorage/pathstoragetest/BUILD.bazel
+++ b/go/lib/pathstorage/pathstoragetest/BUILD.bazel
@@ -20,7 +20,7 @@ go_test(
     deps = [
         "//go/lib/config:go_default_library",
         "//go/lib/pathstorage:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
     ],
 )
diff --git a/go/lib/pathstorage/pathstoragetest/config_test.go b/go/lib/pathstorage/pathstoragetest/config_test.go
index b55d3a3a5..f8e224f4d 100644
--- a/go/lib/pathstorage/pathstoragetest/config_test.go
+++ b/go/lib/pathstorage/pathstoragetest/config_test.go
@@ -18,7 +18,7 @@ import (
 	"bytes"
 	"testing"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 	"github.com/stretchr/testify/assert"
 
 	"github.com/scionproto/scion/go/lib/config"
@@ -30,9 +30,8 @@ func TestPathDBConfSample(t *testing.T) {
 	var cfg pathstorage.PathDBConf
 	cfg.Sample(&sample, nil, map[string]string{config.ID: "test"})
 	InitTestPathDBConf(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckTestPathDBConf(t, &cfg, "test")
 }
 
@@ -41,8 +40,7 @@ func TestRevCacheConfSample(t *testing.T) {
 	var cfg pathstorage.RevCacheConf
 	cfg.Sample(&sample, nil, map[string]string{config.ID: "test"})
 	InitTestRevCacheConf(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckTestRevCacheConf(t, &cfg)
 }
diff --git a/go/lib/truststorage/truststoragetest/BUILD.bazel b/go/lib/truststorage/truststoragetest/BUILD.bazel
index 8482f85af..cf5e18f00 100644
--- a/go/lib/truststorage/truststoragetest/BUILD.bazel
+++ b/go/lib/truststorage/truststoragetest/BUILD.bazel
@@ -20,7 +20,7 @@ go_test(
     deps = [
         "//go/lib/config:go_default_library",
         "//go/lib/truststorage:go_default_library",
-        "@com_github_burntsushi_toml//:go_default_library",
+        "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
     ],
 )
diff --git a/go/lib/truststorage/truststoragetest/config_test.go b/go/lib/truststorage/truststoragetest/config_test.go
index f80141333..2ea431b2a 100644
--- a/go/lib/truststorage/truststoragetest/config_test.go
+++ b/go/lib/truststorage/truststoragetest/config_test.go
@@ -18,7 +18,7 @@ import (
 	"bytes"
 	"testing"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 	"github.com/stretchr/testify/assert"
 
 	"github.com/scionproto/scion/go/lib/config"
@@ -30,9 +30,8 @@ func TestConfigSample(t *testing.T) {
 	var cfg truststorage.TrustDBConf
 	cfg.Sample(&sample, nil, map[string]string{config.ID: "test"})
 	InitTestConfig(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckTestConfig(t, &cfg, "test")
 }
 
@@ -41,8 +40,7 @@ func TestRenewalConfigSample(t *testing.T) {
 	var cfg truststorage.RenewalDBConf
 	cfg.Sample(&sample, nil, map[string]string{config.ID: "test"})
 	InitRenewalTestConfig(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckRenewalTestConfig(t, &cfg, "test")
 }
diff --git a/go/pkg/sciond/config/config_test.go b/go/pkg/sciond/config/config_test.go
index 8b55ab3d0..27b1b096e 100644
--- a/go/pkg/sciond/config/config_test.go
+++ b/go/pkg/sciond/config/config_test.go
@@ -18,7 +18,7 @@ import (
 	"bytes"
 	"testing"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 	"github.com/stretchr/testify/assert"
 
 	"github.com/scionproto/scion/go/lib/env/envtest"
@@ -34,9 +34,8 @@ func TestConfigSample(t *testing.T) {
 	cfg.Sample(&sample, nil, nil)
 
 	InitTestConfig(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckTestConfig(t, &cfg, idSample)
 }
 
diff --git a/go/sig/internal/sigconfig/conf_test.go b/go/sig/internal/sigconfig/conf_test.go
index 16ca086cf..242012aff 100644
--- a/go/sig/internal/sigconfig/conf_test.go
+++ b/go/sig/internal/sigconfig/conf_test.go
@@ -19,7 +19,7 @@ import (
 	"net"
 	"testing"
 
-	"github.com/BurntSushi/toml"
+	"github.com/pelletier/go-toml"
 	"github.com/stretchr/testify/assert"
 
 	"github.com/scionproto/scion/go/lib/env/envtest"
@@ -33,9 +33,8 @@ func TestConfigSample(t *testing.T) {
 	cfg.Sample(&sample, nil, nil)
 
 	InitTestConfig(&cfg)
-	meta, err := toml.Decode(sample.String(), &cfg)
+	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
 	assert.NoError(t, err)
-	assert.Empty(t, meta.Undecoded())
 	CheckTestConfig(t, &cfg, idSample)
 }
 
diff --git a/licenses/data/com_github_burntsushi_toml/cmd/toml-test-decoder/COPYING b/licenses/data/com_github_burntsushi_toml/cmd/toml-test-decoder/COPYING
deleted file mode 100644
index 01b574320..000000000
--- a/licenses/data/com_github_burntsushi_toml/cmd/toml-test-decoder/COPYING
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 TOML authors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/licenses/data/com_github_burntsushi_toml/cmd/toml-test-encoder/COPYING b/licenses/data/com_github_burntsushi_toml/cmd/toml-test-encoder/COPYING
deleted file mode 100644
index 01b574320..000000000
--- a/licenses/data/com_github_burntsushi_toml/cmd/toml-test-encoder/COPYING
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 TOML authors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.