Repository: envoyproxy/gateway
Pull request #3777 (2024-07-08 04:31:01)

build(deps): bump actions/upload-artifact from 4.3.3 to 4.3.4
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.3 to 4.3.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's releases</a>.</em></p>
<blockquote>
<h2>v4.3.4</h2>
<h2>What's Changed</h2>
<ul>
<li>Update <code>@​actions/artifact</code> version, bump dependencies by <a href="https://github.com/robherley"><code>@​robherley</code></a> in <a href="https://redirect.github.com/actions/upload-artifact/pull/584">actions/upload-artifact#584</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/actions/upload-artifact/compare/v4.3.3...v4.3.4">https://github.com/actions/upload-artifact/compare/v4.3.3...v4.3.4</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/actions/upload-artifact/commit/0b2256b8c012f0828dc542b3febcab082c67f72b"><code>0b2256b</code></a> Merge pull request <a href="https://redirect.github.com/actions/upload-artifact/issues/584">#584</a> from actions/robherley/bump-pkgs</li>
<li><a href="https://github.com/actions/upload-artifact/commit/488dcefb9bf01619ac19bad29c5c5409a1e4dd4c"><code>488dcef</code></a> licensed cache</li>
<li><a href="https://github.com/actions/upload-artifact/commit/04c51f57662651dd3333286989e2db1111c0fd07"><code>04c51f5</code></a> ncc</li>
<li><a href="https://github.com/actions/upload-artifact/commit/32a9e276a8f8ac18b4b2dce8213ed340ed4e5ed8"><code>32a9e27</code></a> bump <code>@​actions/artifact</code> and npm audit</li>
<li><a href="https://github.com/actions/upload-artifact/commit/552bf3722c16e81001aea7db72d8cedf64eb5f68"><code>552bf37</code></a> new version</li>
<li><a href="https://github.com/actions/upload-artifact/commit/79616d2ded92999fceefea2ca2e4bdf6101fa919"><code>79616d2</code></a> Merge pull request <a href="https://redirect.github.com/actions/upload-artifact/issues/565">#565</a> from actions/eggyhead/use-artifact-v2.1.6</li>
<li>See full diff in <a href="https://github.com/actions/upload-artifact/compare/65462800fd760344b1a7b4382951275a0abb4808...0b2256b8c012f0828dc542b3febcab082c67f72b">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=4.3.3&new-version=4.3.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/envoyproxy/gateway/pull/3777?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 68.96%. Comparing base [(`9e13e1a`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/9e13e1ab24dbcd931bbde28ebad959b7a6087e17?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) to head [(`8206c72`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/8206c72b1bc5296647f884b43d0da99e2c4ca7b4?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #3777      +/-   ##
==========================================
- Coverage   69.00%   68.96%   -0.05%     
==========================================
  Files         176      176              
  Lines       21751    21751              
==========================================
- Hits        15010    15001       -9     
- Misses       5661     5667       +6     
- Partials     1080     1083       +3     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/envoyproxy/gateway/pull/3777?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).


Patch:
diff --git a/.github/workflows/experimental_conformance.yaml b/.github/workflows/experimental_conformance.yaml
index 7eeddda3f..4c2d2e60f 100644
--- a/.github/workflows/experimental_conformance.yaml
+++ b/.github/workflows/experimental_conformance.yaml
@@ -32,7 +32,7 @@ jobs:
       run: make experimental-conformance
 
     - name: Upload Conformance Report
-      uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808  # v4.3.3
+      uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b  # v4.3.4
       with:
         name: conformance-report-k8s-${{ matrix.version }}
         path: ./test/conformance/conformance-report-k8s-${{ matrix.version }}.yaml
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 03b7272a1..a7b7847bf 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -33,7 +33,7 @@ jobs:
         publish_results: true
 
     - name: "Upload artifact"
-      uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808  # v4.3.3
+      uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b  # v4.3.4
       with:
         name: SARIF file
         path: results.sarif
diff --git a/api/v1alpha1/accesslogging_types.go b/api/v1alpha1/accesslogging_types.go
index 51ecf0be8..765fa4de7 100644
--- a/api/v1alpha1/accesslogging_types.go
+++ b/api/v1alpha1/accesslogging_types.go
@@ -18,7 +18,9 @@ type ProxyAccessLog struct {
 
 type ProxyAccessLogSetting struct {
 	// Format defines the format of accesslog.
-	Format ProxyAccessLogFormat `json:"format"`
+	// This will be ignored if sink type is ALS.
+	// +optional
+	Format *ProxyAccessLogFormat `json:"format"`
 	// Matches defines the match conditions for accesslog in CEL expression.
 	// An accesslog will be emitted only when one or more match conditions are evaluated to true.
 	// Invalid [CEL](https://www.envoyproxy.io/docs/envoy/latest/xds/type/v3/cel.proto.html#common-expression-language-cel-proto) expressions will be ignored.
diff --git a/api/v1alpha1/validation/envoyproxy_validate.go b/api/v1alpha1/validation/envoyproxy_validate.go
index c33c8832b..b4d8b6b73 100644
--- a/api/v1alpha1/validation/envoyproxy_validate.go
+++ b/api/v1alpha1/validation/envoyproxy_validate.go
@@ -246,16 +246,18 @@ func validateProxyAccessLog(accessLog *egv1a1.ProxyAccessLog) []error {
 	var errs []error
 
 	for _, setting := range accessLog.Settings {
-		switch setting.Format.Type {
-		case egv1a1.ProxyAccessLogFormatTypeText:
-			if setting.Format.Text == nil {
-				err := fmt.Errorf("unable to configure access log when using Text format but \"text\" field being empty")
-				errs = append(errs, err)
-			}
-		case egv1a1.ProxyAccessLogFormatTypeJSON:
-			if setting.Format.JSON == nil {
-				err := fmt.Errorf("unable to configure access log when using JSON format but \"json\" field being empty")
-				errs = append(errs, err)
+		if setting.Format != nil {
+			switch setting.Format.Type {
+			case egv1a1.ProxyAccessLogFormatTypeText:
+				if setting.Format.Text == nil {
+					err := fmt.Errorf("unable to configure access log when using Text format but \"text\" field being empty")
+					errs = append(errs, err)
+				}
+			case egv1a1.ProxyAccessLogFormatTypeJSON:
+				if setting.Format.JSON == nil {
+					err := fmt.Errorf("unable to configure access log when using JSON format but \"json\" field being empty")
+					errs = append(errs, err)
+				}
 			}
 		}
 
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 6e55a9d29..3ea39b669 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -3739,7 +3739,11 @@ func (in *ProxyAccessLogFormat) DeepCopy() *ProxyAccessLogFormat {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *ProxyAccessLogSetting) DeepCopyInto(out *ProxyAccessLogSetting) {
 	*out = *in
-	in.Format.DeepCopyInto(&out.Format)
+	if in.Format != nil {
+		in, out := &in.Format, &out.Format
+		*out = new(ProxyAccessLogFormat)
+		(*in).DeepCopyInto(*out)
+	}
 	if in.Matches != nil {
 		in, out := &in.Matches, &out.Matches
 		*out = make([]string, len(*in))
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
index 31f954ac8..373325702 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
@@ -10241,7 +10241,9 @@ spec:
                         items:
                           properties:
                             format:
-                              description: Format defines the format of accesslog.
+                              description: |-
+                                Format defines the format of accesslog.
+                                This will be ignored if sink type is ALS.
                               properties:
                                 json:
                                   additionalProperties:
@@ -10586,7 +10588,6 @@ spec:
                               minItems: 1
                               type: array
                           required:
-                          - format
                           - sinks
                           type: object
                         maxItems: 50
diff --git a/go.mod b/go.mod
index 351d28e9b..44506c169 100644
--- a/go.mod
+++ b/go.mod
@@ -34,13 +34,13 @@ require (
 	github.com/stretchr/testify v1.9.0
 	github.com/telepresenceio/watchable v0.0.0-20220726211108-9bb86f92afa7
 	github.com/tsaarni/certyaml v0.9.3
-	go.opentelemetry.io/otel v1.27.0
-	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0
-	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0
-	go.opentelemetry.io/otel/exporters/prometheus v0.49.0
-	go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.27.0
-	go.opentelemetry.io/otel/metric v1.27.0
-	go.opentelemetry.io/otel/sdk/metric v1.27.0
+	go.opentelemetry.io/otel v1.28.0
+	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0
+	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0
+	go.opentelemetry.io/otel/exporters/prometheus v0.50.0
+	go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0
+	go.opentelemetry.io/otel/metric v1.28.0
+	go.opentelemetry.io/otel/sdk/metric v1.28.0
 	go.opentelemetry.io/proto/otlp v1.3.1
 	go.uber.org/zap v1.27.0
 	golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
@@ -188,8 +188,8 @@ require (
 	github.com/sirupsen/logrus v1.9.3 // indirect
 	github.com/tsaarni/x500dn v1.0.0 // indirect
 	github.com/xlab/treeprint v1.2.0 // indirect
-	go.opentelemetry.io/otel/sdk v1.27.0
-	go.opentelemetry.io/otel/trace v1.27.0 // indirect
+	go.opentelemetry.io/otel/sdk v1.28.0
+	go.opentelemetry.io/otel/trace v1.28.0 // indirect
 	go.starlark.net v0.0.0-20240520160348-046347dcd104 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
 	golang.org/x/mod v0.18.0 // indirect
@@ -201,8 +201,8 @@ require (
 	golang.org/x/time v0.5.0 // indirect
 	golang.org/x/tools v0.22.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	k8s.io/component-base v0.30.2 // indirect
diff --git a/go.sum b/go.sum
index 93f0e887a..056228974 100644
--- a/go.sum
+++ b/go.sum
@@ -691,28 +691,28 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
 go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg=
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q=
-go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg=
-go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc=
+go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
+go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 h1:U2guen0GhqH8o/G2un8f/aG/y++OuW6MyCo6hT9prXk=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0/go.mod h1:yeGZANgEcpdx/WK0IvvRFC+2oLiMS2u4L/0Rj2M2Qr0=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0 h1:aLmmtjRke7LPDQ3lvpFz+kNEH43faFhzW7v8BFIEydg=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0/go.mod h1:TC1pyCt6G9Sjb4bQpShH+P5R53pO6ZuGnHuuln9xMeE=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
-go.opentelemetry.io/otel/exporters/prometheus v0.49.0 h1:Er5I1g/YhfYv9Affk9nJLfH/+qCCVVg1f2R9AbJfqDQ=
-go.opentelemetry.io/otel/exporters/prometheus v0.49.0/go.mod h1:KfQ1wpjf3zsHjzP149P4LyAwWRupc6c7t1ZJ9eXpKQM=
-go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.27.0 h1:/jlt1Y8gXWiHG9FBx6cJaIC5hYx5Fe64nC8w5Cylt/0=
-go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.27.0/go.mod h1:bmToOGOBZ4hA9ghphIc1PAf66VA8KOtsuy3+ScStG20=
-go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik=
-go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak=
-go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI=
-go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A=
-go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI=
-go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw=
-go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw=
-go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4=
+go.opentelemetry.io/otel/exporters/prometheus v0.50.0 h1:2Ewsda6hejmbhGFyUvWZjUThC98Cf8Zy6g0zkIimOng=
+go.opentelemetry.io/otel/exporters/prometheus v0.50.0/go.mod h1:pMm5PkUo5YwbLiuEf7t2xg4wbP0/eSJrMxIMxKosynY=
+go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 h1:BJee2iLkfRfl9lc7aFmBwkWxY/RI1RDdXepSF6y8TPE=
+go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0/go.mod h1:DIzlHs3DRscCIBU3Y9YSzPfScwnYnzfnCd4g8zA7bZc=
+go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
+go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
+go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
+go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
+go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08=
+go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg=
+go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
+go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
 go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
 go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
 go.starlark.net v0.0.0-20240520160348-046347dcd104 h1:3qhteRISupnJvaWshOmeqEUs2y9oc/+/ePPvDh3Eygg=
@@ -885,10 +885,10 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw=
-google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 h1:Di6ANFilr+S60a4S61ZM00vLdw0IrQOSMS2/6mrnOU0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
+google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
+google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
diff --git a/internal/cmd/egctl/translate.go b/internal/cmd/egctl/translate.go
index a9d16269b..2bf4cda17 100644
--- a/internal/cmd/egctl/translate.go
+++ b/internal/cmd/egctl/translate.go
@@ -46,6 +46,8 @@ const (
 	gatewayAPIType = "gateway-api"
 	xdsType        = "xds"
 	irType         = "ir"
+
+	dummyClusterIP = "1.2.3.4"
 )
 
 type TranslationResult struct {
@@ -576,7 +578,7 @@ func addMissingServices(requiredServices map[string]*corev1.Service, obj interfa
 			refs = append(refs, rule.BackendRefs...)
 		}
 	case *gwapiv1a2.UDPRoute:
-		protocol = corev1.Protocol(gatewayapi.UDPProtocol)
+		protocol = gatewayapi.UDPProtocol
 		objNamespace = route.Namespace
 		for _, rule := range route.Spec.Rules {
 			refs = append(refs, rule.BackendRefs...)
@@ -609,12 +611,11 @@ func addMissingServices(requiredServices map[string]*corev1.Service, obj interfa
 				},
 				Spec: corev1.ServiceSpec{
 					// Just a dummy IP
-					ClusterIP: "127.0.0.1",
+					ClusterIP: dummyClusterIP,
 					Ports:     []corev1.ServicePort{servicePort},
 				},
 			}
 			requiredServices[key] = service
-
 		} else {
 			inserted := false
 			for _, port := range service.Spec.Ports {
@@ -792,6 +793,10 @@ func kubernetesYAMLToResources(str string, addMissingResources bool) (*gatewayap
 				},
 				Spec: typedSpec.(corev1.ServiceSpec),
 			}
+			if addMissingResources && len(service.Spec.ClusterIP) == 0 {
+				// fill with dummy IP when service clusterIP is empty
+				service.Spec.ClusterIP = dummyClusterIP
+			}
 			resources.Services = append(resources.Services, service)
 		case egv1a1.KindEnvoyPatchPolicy:
 			typedSpec := spec.Interface()
diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go
index 1bef8ca52..4eac0e11c 100644
--- a/internal/gatewayapi/listener.go
+++ b/internal/gatewayapi/listener.go
@@ -247,6 +247,16 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
 	irAccessLog := &ir.AccessLog{}
 	// translate the access log configuration to the IR
 	for i, accessLog := range envoyproxy.Spec.Telemetry.AccessLog.Settings {
+		var format egv1a1.ProxyAccessLogFormat
+		if accessLog.Format != nil {
+			format = *accessLog.Format
+		} else {
+			format = egv1a1.ProxyAccessLogFormat{
+				Type: egv1a1.ProxyAccessLogFormatTypeText,
+				// Empty text format means default format
+			}
+		}
+
 		for j, sink := range accessLog.Sinks {
 			switch sink.Type {
 			case egv1a1.ProxyAccessLogSinkTypeFile:
@@ -254,21 +264,21 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
 					continue
 				}
 
-				switch accessLog.Format.Type {
+				switch format.Type {
 				case egv1a1.ProxyAccessLogFormatTypeText:
 					al := &ir.TextAccessLog{
-						Format: accessLog.Format.Text,
+						Format: format.Text,
 						Path:   sink.File.Path,
 					}
 					irAccessLog.Text = append(irAccessLog.Text, al)
 				case egv1a1.ProxyAccessLogFormatTypeJSON:
-					if len(accessLog.Format.JSON) == 0 {
+					if len(format.JSON) == 0 {
 						// TODO: use a default JSON format if not specified?
 						continue
 					}
 
 					al := &ir.JSONAccessLog{
-						JSON: accessLog.Format.JSON,
+						JSON: format.JSON,
 						Path: sink.File.Path,
 					}
 					irAccessLog.JSON = append(irAccessLog.JSON, al)
@@ -309,11 +319,11 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
 					al.HTTP = http
 				}
 
-				switch accessLog.Format.Type {
+				switch format.Type {
 				case egv1a1.ProxyAccessLogFormatTypeJSON:
-					al.Attributes = accessLog.Format.JSON
+					al.Attributes = format.JSON
 				case egv1a1.ProxyAccessLogFormatTypeText:
-					al.Text = accessLog.Format.Text
+					al.Text = format.Text
 				}
 
 				irAccessLog.ALS = append(irAccessLog.ALS, al)
@@ -348,11 +358,11 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
 					al.Authority = host
 				}
 
-				switch accessLog.Format.Type {
+				switch format.Type {
 				case egv1a1.ProxyAccessLogFormatTypeJSON:
-					al.Attributes = accessLog.Format.JSON
+					al.Attributes = format.JSON
 				case egv1a1.ProxyAccessLogFormatTypeText:
-					al.Text = accessLog.Format.Text
+					al.Text = format.Text
 				}
 
 				irAccessLog.OpenTelemetry = append(irAccessLog.OpenTelemetry, al)


Test patch:
diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml
index 441377a0e..8ab5cc2c2 100644
--- a/.github/workflows/build_and_test.yaml
+++ b/.github/workflows/build_and_test.yaml
@@ -74,7 +74,7 @@ jobs:
       run: make build-multiarch PLATFORMS="linux_amd64 linux_arm64"
 
     - name: Upload EG Binaries
-      uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808  # v4.3.3
+      uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b  # v4.3.4
       with:
         name: envoy-gateway
         path: bin/
diff --git a/api/v1alpha1/validation/envoyproxy_validate_test.go b/api/v1alpha1/validation/envoyproxy_validate_test.go
index b4bb760e0..591c184fd 100644
--- a/api/v1alpha1/validation/envoyproxy_validate_test.go
+++ b/api/v1alpha1/validation/envoyproxy_validate_test.go
@@ -408,7 +408,7 @@ func TestValidateEnvoyProxy(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: egv1a1.ProxyAccessLogFormatTypeText,
 									},
 								},
@@ -431,7 +431,7 @@ func TestValidateEnvoyProxy(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: egv1a1.ProxyAccessLogFormatTypeText,
 										Text: ptr.To("[%START_TIME%]"),
 									},
diff --git a/internal/cmd/egctl/testdata/translate/in/no-service-cluster-ip.yaml b/internal/cmd/egctl/testdata/translate/in/no-service-cluster-ip.yaml
new file mode 100644
index 000000000..312e12379
--- /dev/null
+++ b/internal/cmd/egctl/testdata/translate/in/no-service-cluster-ip.yaml
@@ -0,0 +1,55 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: GatewayClass
+metadata:
+  name: eg
+spec:
+  controllerName: gateway.envoyproxy.io/gatewayclass-controller
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+  name: eg
+spec:
+  gatewayClassName: eg
+  listeners:
+    - name: http
+      protocol: HTTP
+      port: 80
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: backend
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: backend
+  labels:
+    app: backend1
+    service: backend1
+spec:
+  ports:
+    - name: http
+      port: 8080
+      targetPort: 8080
+  selector:
+    app: backend
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: routes
+spec:
+  parentRefs:
+    - name: eg
+  rules:
+    - backendRefs:
+        - group: ""
+          kind: Service
+          name: backend
+          port: 8080
+      matches:
+        - path:
+            type: PathPrefix
+            value: /service
diff --git a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml
index 1acb8adf4..ac5bde3ed 100644
--- a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml
@@ -749,7 +749,7 @@ xds:
             - endpoint:
                 address:
                   socketAddress:
-                    address: 127.0.0.1
+                    address: 1.2.3.4
                     portValue: 3000
               loadBalancingWeight: 1
             loadBalancingWeight: 1
@@ -763,7 +763,7 @@ xds:
             - endpoint:
                 address:
                   socketAddress:
-                    address: 127.0.0.1
+                    address: 1.2.3.4
                     portValue: 3000
               loadBalancingWeight: 1
             loadBalancingWeight: 1
@@ -777,7 +777,7 @@ xds:
             - endpoint:
                 address:
                   socketAddress:
-                    address: 127.0.0.1
+                    address: 1.2.3.4
                     portValue: 3000
               loadBalancingWeight: 1
             loadBalancingWeight: 1
diff --git a/internal/cmd/egctl/testdata/translate/out/no-service-cluster-ip.all.yaml b/internal/cmd/egctl/testdata/translate/out/no-service-cluster-ip.all.yaml
new file mode 100644
index 000000000..73ea76b01
--- /dev/null
+++ b/internal/cmd/egctl/testdata/translate/out/no-service-cluster-ip.all.yaml
@@ -0,0 +1,303 @@
+xds:
+  envoy-gateway-system/eg:
+    configs:
+    - '@type': type.googleapis.com/envoy.admin.v3.BootstrapConfigDump
+      bootstrap:
+        admin:
+          accessLog:
+          - name: envoy.access_loggers.file
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+              path: /dev/null
+          address:
+            socketAddress:
+              address: 127.0.0.1
+              portValue: 19000
+        dynamicResources:
+          adsConfig:
+            apiType: DELTA_GRPC
+            grpcServices:
+            - envoyGrpc:
+                clusterName: xds_cluster
+            setNodeOnFirstMessageOnly: true
+            transportApiVersion: V3
+          cdsConfig:
+            ads: {}
+            resourceApiVersion: V3
+          ldsConfig:
+            ads: {}
+            resourceApiVersion: V3
+        layeredRuntime:
+          layers:
+          - name: global_config
+            staticLayer:
+              envoy.restart_features.use_eds_cache_for_ads: true
+              re2.max_program_size.error_level: 4294967295
+              re2.max_program_size.warn_level: 1000
+        overloadManager:
+          refreshInterval: 0.250s
+          resourceMonitors:
+          - name: envoy.resource_monitors.global_downstream_max_connections
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig
+              maxActiveDownstreamConnections: "50000"
+        staticResources:
+          clusters:
+          - connectTimeout: 0.250s
+            loadAssignment:
+              clusterName: prometheus_stats
+              endpoints:
+              - lbEndpoints:
+                - endpoint:
+                    address:
+                      socketAddress:
+                        address: 127.0.0.1
+                        portValue: 19000
+            name: prometheus_stats
+            type: STATIC
+          - connectTimeout: 10s
+            loadAssignment:
+              clusterName: xds_cluster
+              endpoints:
+              - lbEndpoints:
+                - endpoint:
+                    address:
+                      socketAddress:
+                        address: envoy-gateway
+                        portValue: 18000
+                  loadBalancingWeight: 1
+                loadBalancingWeight: 1
+            name: xds_cluster
+            transportSocket:
+              name: envoy.transport_sockets.tls
+              typedConfig:
+                '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+                commonTlsContext:
+                  tlsCertificateSdsSecretConfigs:
+                  - name: xds_certificate
+                    sdsConfig:
+                      pathConfigSource:
+                        path: /sds/xds-certificate.json
+                      resourceApiVersion: V3
+                  tlsParams:
+                    tlsMaximumProtocolVersion: TLSv1_3
+                  validationContextSdsSecretConfig:
+                    name: xds_trusted_ca
+                    sdsConfig:
+                      pathConfigSource:
+                        path: /sds/xds-trusted-ca.json
+                      resourceApiVersion: V3
+            type: STRICT_DNS
+            typedExtensionProtocolOptions:
+              envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+                '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+                explicitHttpConfig:
+                  http2ProtocolOptions:
+                    connectionKeepalive:
+                      interval: 30s
+                      timeout: 5s
+          - connectTimeout: 10s
+            loadAssignment:
+              clusterName: wasm_cluster
+              endpoints:
+              - lbEndpoints:
+                - endpoint:
+                    address:
+                      socketAddress:
+                        address: envoy-gateway
+                        portValue: 18002
+                  loadBalancingWeight: 1
+                loadBalancingWeight: 1
+            name: wasm_cluster
+            transportSocket:
+              name: envoy.transport_sockets.tls
+              typedConfig:
+                '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+                commonTlsContext:
+                  tlsCertificateSdsSecretConfigs:
+                  - name: xds_certificate
+                    sdsConfig:
+                      pathConfigSource:
+                        path: /sds/xds-certificate.json
+                      resourceApiVersion: V3
+                  tlsParams:
+                    tlsMaximumProtocolVersion: TLSv1_3
+                  validationContextSdsSecretConfig:
+                    name: xds_trusted_ca
+                    sdsConfig:
+                      pathConfigSource:
+                        path: /sds/xds-trusted-ca.json
+                      resourceApiVersion: V3
+            type: STRICT_DNS
+            typedExtensionProtocolOptions:
+              envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+                '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+                explicitHttpConfig:
+                  http2ProtocolOptions: {}
+          listeners:
+          - address:
+              socketAddress:
+                address: 0.0.0.0
+                portValue: 19001
+            filterChains:
+            - filters:
+              - name: envoy.filters.network.http_connection_manager
+                typedConfig:
+                  '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+                  httpFilters:
+                  - name: envoy.filters.http.health_check
+                    typedConfig:
+                      '@type': type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck
+                      headers:
+                      - name: :path
+                        stringMatch:
+                          exact: /ready
+                      passThroughMode: false
+                  - name: envoy.filters.http.router
+                    typedConfig:
+                      '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+                  routeConfig:
+                    name: local_route
+                    virtualHosts:
+                    - domains:
+                      - '*'
+                      name: prometheus_stats
+                      routes:
+                      - match:
+                          prefix: /stats/prometheus
+                        route:
+                          cluster: prometheus_stats
+                  statPrefix: eg-ready-http
+            name: envoy-gateway-proxy-ready-0.0.0.0-19001
+    - '@type': type.googleapis.com/envoy.admin.v3.EndpointsConfigDump
+      dynamicEndpointConfigs:
+      - endpointConfig:
+          '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment
+          clusterName: httproute/envoy-gateway-system/routes/rule/0
+          endpoints:
+          - lbEndpoints:
+            - endpoint:
+                address:
+                  socketAddress:
+                    address: 1.2.3.4
+                    portValue: 8080
+              loadBalancingWeight: 1
+            loadBalancingWeight: 1
+            locality:
+              region: httproute/envoy-gateway-system/routes/rule/0/backend/0
+    - '@type': type.googleapis.com/envoy.admin.v3.ClustersConfigDump
+      dynamicActiveClusters:
+      - cluster:
+          '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+          circuitBreakers:
+            thresholds:
+            - maxRetries: 1024
+          commonLbConfig:
+            localityWeightedLbConfig: {}
+          connectTimeout: 10s
+          dnsLookupFamily: V4_ONLY
+          edsClusterConfig:
+            edsConfig:
+              ads: {}
+              resourceApiVersion: V3
+            serviceName: httproute/envoy-gateway-system/routes/rule/0
+          lbPolicy: LEAST_REQUEST
+          name: httproute/envoy-gateway-system/routes/rule/0
+          outlierDetection: {}
+          perConnectionBufferLimitBytes: 32768
+          type: EDS
+    - '@type': type.googleapis.com/envoy.admin.v3.ListenersConfigDump
+      dynamicListeners:
+      - activeState:
+          listener:
+            '@type': type.googleapis.com/envoy.config.listener.v3.Listener
+            accessLog:
+            - filter:
+                responseFlagFilter:
+                  flags:
+                  - NR
+              name: envoy.access_loggers.file
+              typedConfig:
+                '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+                logFormat:
+                  textFormatSource:
+                    inlineString: |
+                      {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
+                path: /dev/stdout
+            address:
+              socketAddress:
+                address: 0.0.0.0
+                portValue: 10080
+            defaultFilterChain:
+              filters:
+              - name: envoy.filters.network.http_connection_manager
+                typedConfig:
+                  '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+                  accessLog:
+                  - name: envoy.access_loggers.file
+                    typedConfig:
+                      '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+                      logFormat:
+                        textFormatSource:
+                          inlineString: |
+                            {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
+                      path: /dev/stdout
+                  commonHttpProtocolOptions:
+                    headersWithUnderscoresAction: REJECT_REQUEST
+                  http2ProtocolOptions:
+                    initialConnectionWindowSize: 1048576
+                    initialStreamWindowSize: 65536
+                    maxConcurrentStreams: 100
+                  httpFilters:
+                  - name: envoy.filters.http.router
+                    typedConfig:
+                      '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+                      suppressEnvoyHeaders: true
+                  mergeSlashes: true
+                  normalizePath: true
+                  pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+                  rds:
+                    configSource:
+                      ads: {}
+                      resourceApiVersion: V3
+                    routeConfigName: envoy-gateway-system/eg/http
+                  serverHeaderTransformation: PASS_THROUGH
+                  statPrefix: http
+                  useRemoteAddress: true
+              name: envoy-gateway-system/eg/http
+            drainType: MODIFY_ONLY
+            name: envoy-gateway-system/eg/http
+            perConnectionBufferLimitBytes: 32768
+    - '@type': type.googleapis.com/envoy.admin.v3.RoutesConfigDump
+      dynamicRouteConfigs:
+      - routeConfig:
+          '@type': type.googleapis.com/envoy.config.route.v3.RouteConfiguration
+          ignorePortInHostMatching: true
+          name: envoy-gateway-system/eg/http
+          virtualHosts:
+          - domains:
+            - '*'
+            metadata:
+              filterMetadata:
+                envoy-gateway:
+                  resources:
+                  - kind: ""
+                    name: eg
+                    namespace: envoy-gateway-system
+                    sectionName: http
+            name: envoy-gateway-system/eg/http/*
+            routes:
+            - match:
+                pathSeparatedPrefix: /service
+              metadata:
+                filterMetadata:
+                  envoy-gateway:
+                    resources:
+                    - kind: HTTPRoute
+                      name: routes
+                      namespace: envoy-gateway-system
+              name: httproute/envoy-gateway-system/routes/rule/0/match/0/*
+              route:
+                cluster: httproute/envoy-gateway-system/routes/rule/0
+                upgradeConfigs:
+                - upgradeType: websocket
diff --git a/internal/cmd/egctl/translate_test.go b/internal/cmd/egctl/translate_test.go
index c7d51b0e8..28d07afc9 100644
--- a/internal/cmd/egctl/translate_test.go
+++ b/internal/cmd/egctl/translate_test.go
@@ -281,6 +281,13 @@ func TestTranslate(t *testing.T) {
 			to:     "gateway-api",
 			expect: false,
 		},
+		{
+			name:      "no-service-cluster-ip",
+			from:      "gateway-api",
+			to:        "xds",
+			expect:    true,
+			extraArgs: []string{"--add-missing-resources"},
+		},
 	}
 
 	flag.Parse()
diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.in.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.in.yaml
new file mode 100644
index 000000000..7932d208c
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.in.yaml
@@ -0,0 +1,138 @@
+envoyProxyForGatewayClass:
+  apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: EnvoyProxy
+  metadata:
+    namespace: envoy-gateway-system
+    name: test
+  spec:
+    telemetry:
+      accessLog:
+        settings:
+        - sinks:
+          - type: File
+            file:
+              path: /dev/stdout
+          - type: ALS
+            als:
+              logName: accesslog
+              backendRefs:
+              - name: envoy-als
+                namespace: monitoring
+                port: 9000
+              http:
+                requestHeaders:
+                - x-client-ip-address
+                responseHeaders:
+                - cache-control
+                responseTrailers:
+                - expires
+              type: HTTP
+          - type: ALS
+            als:
+              backendRefs:
+              - name: envoy-als
+                namespace: monitoring
+                port: 9000
+              type: TCP
+          - type: OpenTelemetry
+            openTelemetry:
+              host: otel-collector.monitoring.svc.cluster.local
+              port: 4317
+              resources:
+                k8s.cluster.name: "cluster-1"
+    provider:
+      type: Kubernetes
+      kubernetes:
+        envoyService:
+          type: LoadBalancer
+        envoyDeployment:
+          replicas: 2
+          container:
+            env:
+            - name: env_a
+              value: env_a_value
+            - name: env_b
+              value: env_b_name
+            image: "envoyproxy/envoy:distroless-dev"
+            resources:
+              requests:
+                cpu: 100m
+                memory: 512Mi
+            securityContext:
+              runAsUser: 2000
+              allowPrivilegeEscalation: false
+          pod:
+            annotations:
+              key1: val1
+              key2: val2
+            affinity:
+              nodeAffinity:
+                requiredDuringSchedulingIgnoredDuringExecution:
+                  nodeSelectorTerms:
+                  - matchExpressions:
+                    - key: cloud.google.com/gke-nodepool
+                      operator: In
+                      values:
+                      - router-node
+            tolerations:
+            - effect: NoSchedule
+              key: node-type
+              operator: Exists
+              value: "router"
+            securityContext:
+              runAsUser: 1000
+              runAsGroup: 3000
+              fsGroup: 2000
+              fsGroupChangePolicy: "OnRootMismatch"
+            volumes:
+            - name: certs
+              secret:
+                secretName: envoy-cert
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    namespace: envoy-gateway
+    name: gateway-1
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - name: http
+      protocol: HTTP
+      port: 80
+      allowedRoutes:
+        namespaces:
+          from: Same
+services:
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: envoy-als
+    namespace: monitoring
+  spec:
+    type: ClusterIP
+    ports:
+    - name: grpc
+      port: 9000
+      appProtocol: grpc
+      protocol: TCP
+      targetPort: 9000
+endpointSlices:
+- apiVersion: discovery.k8s.io/v1
+  kind: EndpointSlice
+  metadata:
+    name: endpointslice-envoy-als
+    namespace: monitoring
+    labels:
+      kubernetes.io/service-name: envoy-als
+  addressType: IPv4
+  ports:
+  - name: grpc
+    protocol: TCP
+    appProtocol: grpc
+    port: 9090
+  endpoints:
+  - addresses:
+    - "10.240.0.10"
+    conditions:
+      ready: true
diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml
new file mode 100644
index 000000000..f62207ce2
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml
@@ -0,0 +1,211 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-1
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: Same
+      name: http
+      port: 80
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 0
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+infraIR:
+  envoy-gateway/gateway-1:
+    proxy:
+      config:
+        apiVersion: gateway.envoyproxy.io/v1alpha1
+        kind: EnvoyProxy
+        metadata:
+          creationTimestamp: null
+          name: test
+          namespace: envoy-gateway-system
+        spec:
+          logging: {}
+          provider:
+            kubernetes:
+              envoyDeployment:
+                container:
+                  env:
+                  - name: env_a
+                    value: env_a_value
+                  - name: env_b
+                    value: env_b_name
+                  image: envoyproxy/envoy:distroless-dev
+                  resources:
+                    requests:
+                      cpu: 100m
+                      memory: 512Mi
+                  securityContext:
+                    allowPrivilegeEscalation: false
+                    runAsUser: 2000
+                pod:
+                  affinity:
+                    nodeAffinity:
+                      requiredDuringSchedulingIgnoredDuringExecution:
+                        nodeSelectorTerms:
+                        - matchExpressions:
+                          - key: cloud.google.com/gke-nodepool
+                            operator: In
+                            values:
+                            - router-node
+                  annotations:
+                    key1: val1
+                    key2: val2
+                  securityContext:
+                    fsGroup: 2000
+                    fsGroupChangePolicy: OnRootMismatch
+                    runAsGroup: 3000
+                    runAsUser: 1000
+                  tolerations:
+                  - effect: NoSchedule
+                    key: node-type
+                    operator: Exists
+                    value: router
+                  volumes:
+                  - name: certs
+                    secret:
+                      secretName: envoy-cert
+                replicas: 2
+              envoyService:
+                type: LoadBalancer
+            type: Kubernetes
+          telemetry:
+            accessLog:
+              settings:
+              - format: null
+                sinks:
+                - file:
+                    path: /dev/stdout
+                  type: File
+                - als:
+                    backendRefs:
+                    - name: envoy-als
+                      namespace: monitoring
+                      port: 9000
+                    http:
+                      requestHeaders:
+                      - x-client-ip-address
+                      responseHeaders:
+                      - cache-control
+                      responseTrailers:
+                      - expires
+                    logName: accesslog
+                    type: HTTP
+                  type: ALS
+                - als:
+                    backendRefs:
+                    - name: envoy-als
+                      namespace: monitoring
+                      port: 9000
+                    type: TCP
+                  type: ALS
+                - openTelemetry:
+                    host: otel-collector.monitoring.svc.cluster.local
+                    port: 4317
+                    resources:
+                      k8s.cluster.name: cluster-1
+                  type: OpenTelemetry
+        status: {}
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-1/http
+        ports:
+        - containerPort: 10080
+          name: http-80
+          protocol: HTTP
+          servicePort: 80
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-1
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+      name: envoy-gateway/gateway-1
+xdsIR:
+  envoy-gateway/gateway-1:
+    accessLog:
+      als:
+      - destination:
+          name: accesslog_als_0_1
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 10.240.0.10
+              port: 9090
+            protocol: GRPC
+        http:
+          requestHeaders:
+          - x-client-ip-address
+          responseHeaders:
+          - cache-control
+          responseTrailers:
+          - expires
+        name: accesslog
+        type: HTTP
+      - destination:
+          name: accesslog_als_0_2
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 10.240.0.10
+              port: 9090
+            protocol: GRPC
+        name: envoy-gateway-system/test
+        type: TCP
+      openTelemetry:
+      - authority: otel-collector.monitoring.svc.cluster.local
+        destination:
+          name: accesslog_otel_0_3
+          settings:
+          - endpoints:
+            - host: otel-collector.monitoring.svc.cluster.local
+              port: 4317
+            protocol: GRPC
+            weight: 1
+        resources:
+          k8s.cluster.name: cluster-1
+      text:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: false
+      metadata:
+        kind: Gateway
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+      name: envoy-gateway/gateway-1/http
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 10080
diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-without-format.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-without-format.yaml
new file mode 100644
index 000000000..40aef558e
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-without-format.yaml
@@ -0,0 +1,64 @@
+name: "accesslog"
+accesslog:
+  text:
+  - path: "/dev/stdout"
+  json:
+  - path: "/dev/stdout"
+    json:
+      start_time: "%START_TIME%"
+      method: "%REQ(:METHOD)%"
+      path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
+      protocol: "%PROTOCOL%"
+      response_code: "%RESPONSE_CODE%"
+  als:
+  - destination:
+      name: accesslog/monitoring/envoy-als/port/9000
+      settings:
+      - addressType: IP
+        endpoints:
+        - host: 1.1.1.1
+          port: 9000
+        protocol: GRPC
+        weight: 1
+    http:
+      requestHeaders:
+      - x-client-ip-address
+      responseHeaders:
+      - cache-control
+      responseTrailers:
+      - expires
+    type: HTTP
+  openTelemetry:
+  - attributes:
+      "response_code": "%RESPONSE_CODE%"
+    resources:
+      "cluster_name": "cluster1"
+    authority: "otel-collector.default.svc.cluster.local"
+    destination:
+      name: "accesslog-0"
+      settings:
+      - endpoints:
+        - host: "otel-collector.default.svc.cluster.local"
+          port: 4317
+        protocol: "GRPC"
+http:
+- name: "first-listener"
+  address: "0.0.0.0"
+  port: 10080
+  hostnames:
+  - "*"
+  path:
+    mergeSlashes: true
+    escapedSlashesAction: UnescapeAndRedirect
+  routes:
+  - name: "direct-route"
+    hostname: "*"
+    destination:
+      name: "direct-route-dest"
+      settings:
+      - endpoints:
+        - host: "1.2.3.4"
+          port: 50000
+    directResponse:
+      body: "Unknown custom filter type: UnsupportedType"
+      statusCode: 500
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.clusters.yaml
new file mode 100644
index 000000000..6ba4705c1
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.clusters.yaml
@@ -0,0 +1,71 @@
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig:
+    localityWeightedLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_ONLY
+  edsClusterConfig:
+    edsConfig:
+      ads: {}
+      resourceApiVersion: V3
+    serviceName: direct-route-dest
+  lbPolicy: LEAST_REQUEST
+  name: direct-route-dest
+  outlierDetection: {}
+  perConnectionBufferLimitBytes: 32768
+  type: EDS
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig:
+    localityWeightedLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_ONLY
+  edsClusterConfig:
+    edsConfig:
+      ads: {}
+      resourceApiVersion: V3
+    serviceName: accesslog/monitoring/envoy-als/port/9000
+  lbPolicy: LEAST_REQUEST
+  name: accesslog/monitoring/envoy-als/port/9000
+  outlierDetection: {}
+  perConnectionBufferLimitBytes: 32768
+  type: EDS
+  typedExtensionProtocolOptions:
+    envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+      '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+      explicitHttpConfig:
+        http2ProtocolOptions: {}
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig:
+    localityWeightedLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_ONLY
+  dnsRefreshRate: 30s
+  lbPolicy: LEAST_REQUEST
+  loadAssignment:
+    clusterName: accesslog-0
+    endpoints:
+    - lbEndpoints:
+      - endpoint:
+          address:
+            socketAddress:
+              address: otel-collector.default.svc.cluster.local
+              portValue: 4317
+        loadBalancingWeight: 1
+      loadBalancingWeight: 1
+      locality:
+        region: accesslog-0/backend/0
+  name: accesslog-0
+  outlierDetection: {}
+  perConnectionBufferLimitBytes: 32768
+  respectDnsTtl: true
+  type: STRICT_DNS
+  typedExtensionProtocolOptions:
+    envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+      '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+      explicitHttpConfig:
+        http2ProtocolOptions: {}
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.endpoints.yaml
new file mode 100644
index 000000000..2ce2e6da0
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.endpoints.yaml
@@ -0,0 +1,24 @@
+- clusterName: direct-route-dest
+  endpoints:
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 1.2.3.4
+            portValue: 50000
+      loadBalancingWeight: 1
+    loadBalancingWeight: 1
+    locality:
+      region: direct-route-dest/backend/0
+- clusterName: accesslog/monitoring/envoy-als/port/9000
+  endpoints:
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 1.1.1.1
+            portValue: 9000
+      loadBalancingWeight: 1
+    loadBalancingWeight: 1
+    locality:
+      region: accesslog/monitoring/envoy-als/port/9000/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.listeners.yaml
new file mode 100644
index 000000000..4eec55961
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.listeners.yaml
@@ -0,0 +1,177 @@
+- accessLog:
+  - filter:
+      responseFlagFilter:
+        flags:
+        - NR
+    name: envoy.access_loggers.file
+    typedConfig:
+      '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+      logFormat:
+        textFormatSource:
+          inlineString: |
+            {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
+      path: /dev/stdout
+  - filter:
+      responseFlagFilter:
+        flags:
+        - NR
+    name: envoy.access_loggers.file
+    typedConfig:
+      '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+      logFormat:
+        jsonFormat:
+          method: '%REQ(:METHOD)%'
+          path: '%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%'
+          protocol: '%PROTOCOL%'
+          response_code: '%RESPONSE_CODE%'
+          start_time: '%START_TIME%'
+      path: /dev/stdout
+  - filter:
+      responseFlagFilter:
+        flags:
+        - NR
+    name: envoy.access_loggers.http_grpc
+    typedConfig:
+      '@type': type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.HttpGrpcAccessLogConfig
+      additionalRequestHeadersToLog:
+      - x-client-ip-address
+      additionalResponseHeadersToLog:
+      - cache-control
+      additionalResponseTrailersToLog:
+      - expires
+      commonConfig:
+        grpcService:
+          envoyGrpc:
+            clusterName: accesslog/monitoring/envoy-als/port/9000
+        transportApiVersion: V3
+  - filter:
+      responseFlagFilter:
+        flags:
+        - NR
+    name: envoy.access_loggers.open_telemetry
+    typedConfig:
+      '@type': type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig
+      attributes:
+        values:
+        - key: k8s.namespace.name
+          value:
+            stringValue: '%ENVIRONMENT(ENVOY_GATEWAY_NAMESPACE)%'
+        - key: k8s.pod.name
+          value:
+            stringValue: '%ENVIRONMENT(ENVOY_POD_NAME)%'
+        - key: response_code
+          value:
+            stringValue: '%RESPONSE_CODE%'
+      body:
+        stringValue: |
+          {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
+      commonConfig:
+        grpcService:
+          envoyGrpc:
+            authority: otel-collector.default.svc.cluster.local
+            clusterName: accesslog-0
+        logName: otel_envoy_accesslog
+        transportApiVersion: V3
+      resourceAttributes:
+        values:
+        - key: cluster_name
+          value:
+            stringValue: cluster1
+  address:
+    socketAddress:
+      address: 0.0.0.0
+      portValue: 10080
+  defaultFilterChain:
+    filters:
+    - name: envoy.filters.network.http_connection_manager
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+        accessLog:
+        - name: envoy.access_loggers.file
+          typedConfig:
+            '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+            logFormat:
+              textFormatSource:
+                inlineString: |
+                  {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
+            path: /dev/stdout
+        - name: envoy.access_loggers.file
+          typedConfig:
+            '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+            logFormat:
+              jsonFormat:
+                method: '%REQ(:METHOD)%'
+                path: '%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%'
+                protocol: '%PROTOCOL%'
+                response_code: '%RESPONSE_CODE%'
+                start_time: '%START_TIME%'
+            path: /dev/stdout
+        - name: envoy.access_loggers.http_grpc
+          typedConfig:
+            '@type': type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.HttpGrpcAccessLogConfig
+            additionalRequestHeadersToLog:
+            - x-client-ip-address
+            additionalResponseHeadersToLog:
+            - cache-control
+            additionalResponseTrailersToLog:
+            - expires
+            commonConfig:
+              grpcService:
+                envoyGrpc:
+                  clusterName: accesslog/monitoring/envoy-als/port/9000
+              transportApiVersion: V3
+        - name: envoy.access_loggers.open_telemetry
+          typedConfig:
+            '@type': type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig
+            attributes:
+              values:
+              - key: k8s.namespace.name
+                value:
+                  stringValue: '%ENVIRONMENT(ENVOY_GATEWAY_NAMESPACE)%'
+              - key: k8s.pod.name
+                value:
+                  stringValue: '%ENVIRONMENT(ENVOY_POD_NAME)%'
+              - key: response_code
+                value:
+                  stringValue: '%RESPONSE_CODE%'
+            body:
+              stringValue: |
+                {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
+            commonConfig:
+              grpcService:
+                envoyGrpc:
+                  authority: otel-collector.default.svc.cluster.local
+                  clusterName: accesslog-0
+              logName: otel_envoy_accesslog
+              transportApiVersion: V3
+            resourceAttributes:
+              values:
+              - key: cluster_name
+                value:
+                  stringValue: cluster1
+        commonHttpProtocolOptions:
+          headersWithUnderscoresAction: REJECT_REQUEST
+        http2ProtocolOptions:
+          initialConnectionWindowSize: 1048576
+          initialStreamWindowSize: 65536
+          maxConcurrentStreams: 100
+        httpFilters:
+        - name: envoy.filters.http.router
+          typedConfig:
+            '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+            suppressEnvoyHeaders: true
+        mergeSlashes: true
+        normalizePath: true
+        pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+        rds:
+          configSource:
+            ads: {}
+            resourceApiVersion: V3
+          routeConfigName: first-listener
+        serverHeaderTransformation: PASS_THROUGH
+        statPrefix: http
+        useRemoteAddress: true
+    name: first-listener
+  drainType: MODIFY_ONLY
+  name: first-listener
+  perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.routes.yaml
new file mode 100644
index 000000000..d4a7fa5ae
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.routes.yaml
@@ -0,0 +1,14 @@
+- ignorePortInHostMatching: true
+  name: first-listener
+  virtualHosts:
+  - domains:
+    - '*'
+    name: first-listener/*
+    routes:
+    - directResponse:
+        body:
+          inlineString: 'Unknown custom filter type: UnsupportedType'
+        status: 500
+      match:
+        prefix: /
+      name: direct-route
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index fc824c824..6548b6b7b 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -2723,7 +2723,7 @@ _Appears in:_
 
 | Field | Type | Required | Description |
 | ---   | ---  | ---      | ---         |
-| `format` | _[ProxyAccessLogFormat](#proxyaccesslogformat)_ |  true  | Format defines the format of accesslog. |
+| `format` | _[ProxyAccessLogFormat](#proxyaccesslogformat)_ |  false  | Format defines the format of accesslog.<br />This will be ignored if sink type is ALS. |
 | `sinks` | _[ProxyAccessLogSink](#proxyaccesslogsink) array_ |  true  | Sinks defines the sinks of accesslog. |
 
 
diff --git a/site/content/zh/latest/api/extension_types.md b/site/content/zh/latest/api/extension_types.md
index fc824c824..6548b6b7b 100644
--- a/site/content/zh/latest/api/extension_types.md
+++ b/site/content/zh/latest/api/extension_types.md
@@ -2723,7 +2723,7 @@ _Appears in:_
 
 | Field | Type | Required | Description |
 | ---   | ---  | ---      | ---         |
-| `format` | _[ProxyAccessLogFormat](#proxyaccesslogformat)_ |  true  | Format defines the format of accesslog. |
+| `format` | _[ProxyAccessLogFormat](#proxyaccesslogformat)_ |  false  | Format defines the format of accesslog.<br />This will be ignored if sink type is ALS. |
 | `sinks` | _[ProxyAccessLogSink](#proxyaccesslogsink) array_ |  true  | Sinks defines the sinks of accesslog. |
 
 
diff --git a/test/cel-validation/envoyproxy_test.go b/test/cel-validation/envoyproxy_test.go
index 5914e1dbc..f24dfd0eb 100644
--- a/test/cel-validation/envoyproxy_test.go
+++ b/test/cel-validation/envoyproxy_test.go
@@ -278,7 +278,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: "foo",
 									},
 								},
@@ -297,7 +297,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: egv1a1.ProxyAccessLogFormatTypeText,
 									},
 									Sinks: []egv1a1.ProxyAccessLogSink{
@@ -324,7 +324,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: egv1a1.ProxyAccessLogFormatTypeJSON,
 									},
 									Sinks: []egv1a1.ProxyAccessLogSink{
@@ -351,7 +351,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: egv1a1.ProxyAccessLogFormatTypeJSON,
 										Text: ptr.To("[%START_TIME%]"),
 									},
@@ -379,7 +379,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: egv1a1.ProxyAccessLogFormatTypeJSON,
 										JSON: map[string]string{
 											"foo": "bar",
@@ -406,7 +406,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: egv1a1.ProxyAccessLogFormatTypeText,
 										Text: ptr.To("[%START_TIME%]"),
 									},
@@ -431,7 +431,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: egv1a1.ProxyAccessLogFormatTypeText,
 										Text: ptr.To("[%START_TIME%]"),
 									},
@@ -456,7 +456,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: egv1a1.ProxyAccessLogFormatTypeText,
 										Text: ptr.To("[%START_TIME%]"),
 									},
@@ -484,13 +484,6 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
-										Type: egv1a1.ProxyAccessLogFormatTypeJSON,
-										JSON: map[string]string{
-											"attr1": "value1",
-											"attr2": "value2",
-										},
-									},
 									Sinks: []egv1a1.ProxyAccessLogSink{
 										{
 											Type: egv1a1.ProxyAccessLogSinkTypeALS,
@@ -522,10 +515,6 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
-										Type: "Text",
-										Text: ptr.To("[%START_TIME%]"),
-									},
 									Sinks: []egv1a1.ProxyAccessLogSink{
 										{
 											Type: egv1a1.ProxyAccessLogSinkTypeALS,
@@ -559,10 +548,6 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
-										Type: "Text",
-										Text: ptr.To("[%START_TIME%]"),
-									},
 									Sinks: []egv1a1.ProxyAccessLogSink{
 										{
 											Type: egv1a1.ProxyAccessLogSinkTypeALS,
@@ -595,10 +580,6 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
-										Type: "Text",
-										Text: ptr.To("[%START_TIME%]"),
-									},
 									Sinks: []egv1a1.ProxyAccessLogSink{
 										{
 											Type: egv1a1.ProxyAccessLogSinkTypeALS,
@@ -631,10 +612,6 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
-										Type: "Text",
-										Text: ptr.To("[%START_TIME%]"),
-									},
 									Sinks: []egv1a1.ProxyAccessLogSink{
 										{
 											Type: egv1a1.ProxyAccessLogSinkTypeALS,
@@ -659,10 +636,6 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
-										Type: "Text",
-										Text: ptr.To("[%START_TIME%]"),
-									},
 									Sinks: []egv1a1.ProxyAccessLogSink{
 										{
 											Type: egv1a1.ProxyAccessLogSinkTypeALS,
@@ -688,10 +661,6 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
-										Type: "Text",
-										Text: ptr.To("[%START_TIME%]"),
-									},
 									Sinks: []egv1a1.ProxyAccessLogSink{
 										{
 											Type: egv1a1.ProxyAccessLogSinkTypeALS,
@@ -730,7 +699,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: "Text",
 										Text: ptr.To("[%START_TIME%]"),
 									},
@@ -758,7 +727,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: "Text",
 										Text: ptr.To("[%START_TIME%]"),
 									},
@@ -793,7 +762,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: "Text",
 										Text: ptr.To("[%START_TIME%]"),
 									},
@@ -828,7 +797,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: "Text",
 										Text: ptr.To("[%START_TIME%]"),
 									},
@@ -863,7 +832,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: "Text",
 										Text: ptr.To("[%START_TIME%]"),
 									},
@@ -906,7 +875,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: "Text",
 										Text: ptr.To("[%START_TIME%]"),
 									},
@@ -940,7 +909,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
 						AccessLog: &egv1a1.ProxyAccessLog{
 							Settings: []egv1a1.ProxyAccessLogSetting{
 								{
-									Format: egv1a1.ProxyAccessLogFormat{
+									Format: &egv1a1.ProxyAccessLogFormat{
 										Type: "Text",
 										Text: ptr.To("[%START_TIME%]"),
 									},
diff --git a/test/config/gatewayclass.yaml b/test/config/gatewayclass.yaml
index 4c1241a7b..fa07a1593 100644
--- a/test/config/gatewayclass.yaml
+++ b/test/config/gatewayclass.yaml
@@ -60,11 +60,7 @@ spec:
                     port: 4317
                 resources:
                   k8s.cluster.name: "envoy-gateway"
-        - format:
-            type: Text
-            text: |
-              [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"
-          sinks:
+        - sinks:
             - type: ALS
               als:
                 backendRefs:
@@ -169,3 +165,4 @@ metadata:
 spec:
   controllerName: gateway.envoyproxy.io/gatewayclass-controller
 ---
+