diff --git a/caddyconfig/httpcaddyfile/builtins_test.go b/caddyconfig/httpcaddyfile/builtins_test.go
index 496238301..a28229b41 100644
--- a/caddyconfig/httpcaddyfile/builtins_test.go
+++ b/caddyconfig/httpcaddyfile/builtins_test.go
@@ -37,7 +37,6 @@ func TestLogDirectiveSyntax(t *testing.T) {
 					format filter {
 						wrap console
 						fields {
-							common_log delete
 							request>remote_addr ip_mask {
 								ipv4 24
 								ipv6 32
@@ -47,7 +46,7 @@ func TestLogDirectiveSyntax(t *testing.T) {
 				}
 			}
 			`,
-			output:      `{"logging":{"logs":{"default":{"exclude":["http.log.access.log0"]},"log0":{"encoder":{"fields":{"common_log":{"filter":"delete"},"request\u003eremote_addr":{"filter":"ip_mask","ipv4_cidr":24,"ipv6_cidr":32}},"format":"filter","wrap":{"format":"console"}},"include":["http.log.access.log0"]}}},"apps":{"http":{"servers":{"srv0":{"listen":[":8080"],"logs":{"default_logger_name":"log0"}}}}}}`,
+			output:      `{"logging":{"logs":{"default":{"exclude":["http.log.access.log0"]},"log0":{"encoder":{"fields":{"request\u003eremote_addr":{"filter":"ip_mask","ipv4_cidr":24,"ipv6_cidr":32}},"format":"filter","wrap":{"format":"console"}},"include":["http.log.access.log0"]}}},"apps":{"http":{"servers":{"srv0":{"listen":[":8080"],"logs":{"default_logger_name":"log0"}}}}}}`,
 			expectError: false,
 		},
 		{
diff --git a/caddytest/integration/caddyfile_adapt/global_options_log_custom.txt b/caddytest/integration/caddyfile_adapt/global_options_log_custom.txt
index abbca19f6..e37e75e1e 100644
--- a/caddytest/integration/caddyfile_adapt/global_options_log_custom.txt
+++ b/caddytest/integration/caddyfile_adapt/global_options_log_custom.txt
@@ -3,7 +3,6 @@
 		format filter {
 			wrap console
 			fields {
-				common_log delete
 				request>remote_addr ip_mask {
 					ipv4 24
 					ipv6 32
@@ -19,9 +18,6 @@
 			"custom-logger": {
 				"encoder": {
 					"fields": {
-						"common_log": {
-							"filter": "delete"
-						},
 						"request\u003eremote_addr": {
 							"filter": "ip_mask",
 							"ipv4_cidr": 24,
diff --git a/modules/caddyhttp/server.go b/modules/caddyhttp/server.go
index 26384af10..2ddec6065 100644
--- a/modules/caddyhttp/server.go
+++ b/modules/caddyhttp/server.go
@@ -187,7 +187,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 			userID, _ := repl.GetString("http.auth.user.id")
 
 			log("handled request",
-				zap.String("common_log", repl.ReplaceAll(commonLogFormat, commonLogEmptyValue)),
 				zap.String("user_id", userID),
 				zap.Duration("duration", duration),
 				zap.Int("size", wrec.Size()),
@@ -627,14 +626,6 @@ func cloneURL(from, to *url.URL) {
 	}
 }
 
-const (
-	// commonLogFormat is the common log format. https://en.wikipedia.org/wiki/Common_Log_Format
-	commonLogFormat = `{http.request.remote.host} ` + commonLogEmptyValue + ` {http.auth.user.id} [{time.now.common_log}] "{http.request.orig_method} {http.request.orig_uri} {http.request.proto}" {http.response.status} {http.response.size}`
-
-	// commonLogEmptyValue is the common empty log value.
-	commonLogEmptyValue = "-"
-)
-
 // Context keys for HTTP request context values.
 const (
 	// For referencing the server instance
diff --git a/modules/logging/encoders.go b/modules/logging/encoders.go
index 1b5f4a6d0..bc5fe210e 100644
--- a/modules/logging/encoders.go
+++ b/modules/logging/encoders.go
@@ -15,9 +15,6 @@
 package logging
 
 import (
-	"encoding/json"
-	"fmt"
-	"strings"
 	"time"
 
 	"github.com/caddyserver/caddy/v2"
@@ -30,7 +27,6 @@ import (
 func init() {
 	caddy.RegisterModule(ConsoleEncoder{})
 	caddy.RegisterModule(JSONEncoder{})
-	caddy.RegisterModule(SingleFieldEncoder{})
 }
 
 // ConsoleEncoder encodes log entries that are mostly human-readable.
@@ -115,85 +111,6 @@ func (je *JSONEncoder) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
 	return nil
 }
 
-// SingleFieldEncoder writes a log entry that consists entirely
-// of a single string field in the log entry. This is useful
-// for custom, self-encoded log entries that consist of a
-// single field in the structured log entry.
-type SingleFieldEncoder struct {
-	zapcore.Encoder `json:"-"`
-	FieldName       string          `json:"field,omitempty"`
-	FallbackRaw     json.RawMessage `json:"fallback,omitempty" caddy:"namespace=caddy.logging.encoders inline_key=format"`
-}
-
-// CaddyModule returns the Caddy module information.
-func (SingleFieldEncoder) CaddyModule() caddy.ModuleInfo {
-	return caddy.ModuleInfo{
-		ID:  "caddy.logging.encoders.single_field",
-		New: func() caddy.Module { return new(SingleFieldEncoder) },
-	}
-}
-
-// Provision sets up the encoder.
-func (se *SingleFieldEncoder) Provision(ctx caddy.Context) error {
-	caddy.Log().Named("caddy.logging.encoders.single_field").Warn("the 'single_field' encoder is deprecated and will be removed soon!")
-	if se.FallbackRaw != nil {
-		val, err := ctx.LoadModule(se, "FallbackRaw")
-		if err != nil {
-			return fmt.Errorf("loading fallback encoder module: %v", err)
-		}
-		se.Encoder = val.(zapcore.Encoder)
-	}
-	if se.Encoder == nil {
-		se.Encoder = nopEncoder{}
-	}
-	return nil
-}
-
-// Clone wraps the underlying encoder's Clone. This is
-// necessary because we implement our own EncodeEntry,
-// and if we simply let the embedded encoder's Clone
-// be promoted, it would return a clone of that, and
-// we'd lose our SingleFieldEncoder's EncodeEntry.
-func (se SingleFieldEncoder) Clone() zapcore.Encoder {
-	return SingleFieldEncoder{
-		Encoder:   se.Encoder.Clone(),
-		FieldName: se.FieldName,
-	}
-}
-
-// EncodeEntry partially implements the zapcore.Encoder interface.
-func (se SingleFieldEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
-	for _, f := range fields {
-		if f.Key == se.FieldName {
-			buf := bufferpool.Get()
-			buf.AppendString(f.String)
-			if !strings.HasSuffix(f.String, "\n") {
-				buf.AppendByte('\n')
-			}
-			return buf, nil
-		}
-	}
-	if se.Encoder == nil {
-		return nil, fmt.Errorf("no fallback encoder defined")
-	}
-	return se.Encoder.EncodeEntry(ent, fields)
-}
-
-// UnmarshalCaddyfile sets up the module from Caddyfile tokens. Syntax:
-//
-//     single_field <field_name>
-//
-func (se *SingleFieldEncoder) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
-	for d.Next() {
-		var fieldName string
-		if !d.AllArgs(&fieldName) {
-			return d.ArgErr()
-		}
-		se.FieldName = d.Val()
-	}
-	return nil
-}
-
 // LogEncoderConfig holds configuration common to most encoders.
 type LogEncoderConfig struct {
 	MessageKey     *string `json:"message_key,omitempty"`
@@ -350,9 +267,7 @@ var bufferpool = buffer.NewPool()
 var (
 	_ zapcore.Encoder = (*ConsoleEncoder)(nil)
 	_ zapcore.Encoder = (*JSONEncoder)(nil)
-	_ zapcore.Encoder = (*SingleFieldEncoder)(nil)
 
 	_ caddyfile.Unmarshaler = (*ConsoleEncoder)(nil)
 	_ caddyfile.Unmarshaler = (*JSONEncoder)(nil)
-	_ caddyfile.Unmarshaler = (*SingleFieldEncoder)(nil)
 )