Repository: hashicorp/terraform-provider-kubernetes

Issue:
Metadata flattener refactor breaks data resource null checks
<!---
Hi there,

Thank you for opening an issue. Please note that we try to keep the Terraform issue tracker reserved for bug reports and feature requests. For general usage questions, please see: https://www.terraform.io/community.html.
--->


### Terraform Version, Provider Version and Kubernetes Version
<!--- Run `terraform -v` to show the version. If you are not running the latest version of Terraform, please upgrade because your issue may have already been fixed. --->
```
Terraform version: v1.6.4
Kubernetes provider version: v2.26.0
Kubernetes version: v1.29.2
```

### Affected Resource(s)

- data.kubernetes_secret (likely others)

<!-- Please list the resources as a list, for example:
- opc_instance
- opc_storage_volume
If this issue appears to affect multiple resources, it may be an issue with Terraform's core, so please mention this. -->

### Terraform Configuration Files

Before terraform-provider-kubernetes v2.25.0, it was possible to use a data reference for a Kubernetes Secret that doesn't exist yet, and then check whether the value was null in expressions.

```hcl
data "kubernetes_secret" "tls" {
  metadata {
    name = "example"
  }
}

...

locals {
   foo = data.kubernetes_secret.tls.data != null ? "foo" : "bar"
}
```

### Debug Output
<!--Please provider a link to a GitHub Gist containing the complete debug output: https://www.terraform.io/docs/internals/debugging.html. Please do NOT paste the debug output in the issue; just paste a link to the Gist.-->

### Panic Output
<!--If Terraform produced a panic, please provide a link to a GitHub Gist containing the output of the `crash.log`.-->

### Steps to Reproduce
<!-- Please list the steps required to reproduce the issue, for example:
1. `terraform apply` -->

### Expected Behavior
What should have happened?

The prior behavior was useful since you could act on a missing secret in advanced ways. And now that's no longer possible :(

You should be allowed to data reference a non-existent secret and check whether it's value is null. This should not hard error out the workspace.

### Actual Behavior
What actually happened?

Starting with v2.25.0 in [this refactor](https://github.com/hashicorp/terraform-provider-kubernetes/pull/2345), the behavior broke. You just get a hard error and the Terraform workspace is unusable unless you remove the data reference.

```
Error: secrets "example" not found
│ 
│   with module.secrets-sync,
│   on tls-secret/tls.tf line 3, in data "kubernetes_secret" "tls":
│    3: data "kubernetes_secret" "tls" {
```

The prior behavior was useful since you could act on a missing secret in advanced ways. And now that's no longer possible :(

### Important Factoids
<!-- Are there anything atypical about your accounts that we should know? For example: Running in EC2 Classic? Custom version of OpenStack? Tight ACLs?-->

Rolling back to provider v2.24.0 fixes this again.

### References
<!--Are there any other GitHub issues (open or closed) or Pull Requests that should be linked here? For example:-->
- https://github.com/hashicorp/terraform-provider-kubernetes/pull/2345

### Community Note
<!--- Please keep this note for the community --->
* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request
* If you are interested in working on this issue or have submitted a pull request, please leave a comment


Discussion:
@dghubble: cc @arybolovlev @alexsomesan: Hi Dalton,
Thanks for the report and catching this. Indeed, you are right. This does look like a regression, especially as a minor version release.
We'll address it shortly.@alexsomesan: Release 2.29.0 contains the fix.

Solution patch:
diff --git a/.changelog/2464.txt b/.changelog/2464.txt
new file mode 100644
index 00000000..02b51ca2
--- /dev/null
+++ b/.changelog/2464.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+data-sources: revert a recently introduced deviation on datasources where querying a non-existent resource would cause an error (#2434).
+```
diff --git a/kubernetes/data_source_kubernetes_config_map_v1.go b/kubernetes/data_source_kubernetes_config_map_v1.go
index c65cf9fb..70f8d9f0 100644
--- a/kubernetes/data_source_kubernetes_config_map_v1.go
+++ b/kubernetes/data_source_kubernetes_config_map_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -54,6 +55,9 @@ func dataSourceKubernetesConfigMapV1Read(ctx context.Context, d *schema.Resource
 	log.Printf("[INFO] Reading config map %s", metadata.Name)
 	cfgMap, err := conn.CoreV1().ConfigMaps(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_endpoints_v1.go b/kubernetes/data_source_kubernetes_endpoints_v1.go
index 05c4833f..95ca313a 100644
--- a/kubernetes/data_source_kubernetes_endpoints_v1.go
+++ b/kubernetes/data_source_kubernetes_endpoints_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -45,6 +46,9 @@ func dataSourceKubernetesEndpointsV1Read(ctx context.Context, d *schema.Resource
 	log.Printf("[INFO] Reading endpoints %s", metadata.Name)
 	ep, err := conn.CoreV1().Endpoints(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.Errorf("Failed to read endpoint because: %s", err)
 	}
diff --git a/kubernetes/data_source_kubernetes_ingress.go b/kubernetes/data_source_kubernetes_ingress.go
index dd5f5dcd..e0d4210f 100644
--- a/kubernetes/data_source_kubernetes_ingress.go
+++ b/kubernetes/data_source_kubernetes_ingress.go
@@ -10,6 +10,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 	networking "k8s.io/api/networking/v1beta1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -151,6 +152,9 @@ func dataSourceKubernetesIngressRead(ctx context.Context, d *schema.ResourceData
 	log.Printf("[INFO] Reading ingress %s", metadata.Name)
 	ing, err := conn.ExtensionsV1beta1().Ingresses(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_ingress_v1.go b/kubernetes/data_source_kubernetes_ingress_v1.go
index 1aa2865b..b7988c7d 100644
--- a/kubernetes/data_source_kubernetes_ingress_v1.go
+++ b/kubernetes/data_source_kubernetes_ingress_v1.go
@@ -11,6 +11,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
 	networking "k8s.io/api/networking/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -162,6 +163,9 @@ func dataSourceKubernetesIngressV1Read(ctx context.Context, d *schema.ResourceDa
 	log.Printf("[INFO] Reading ingress %s", metadata.Name)
 	ing, err := conn.NetworkingV1().Ingresses(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1.go b/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1.go
index 9e29bcbd..44d8949b 100644
--- a/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1.go
+++ b/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1.go
@@ -11,6 +11,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
 	admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -124,6 +125,9 @@ func dataSourceKubernetesMutatingWebhookConfigurationV1Read(ctx context.Context,
 	log.Printf("[INFO] Reading mutating webhook configuration %s", metadata.Name)
 	cfg, err := conn.AdmissionregistrationV1().MutatingWebhookConfigurations().Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_namespace_v1.go b/kubernetes/data_source_kubernetes_namespace_v1.go
index 06b7de5e..6843d37f 100644
--- a/kubernetes/data_source_kubernetes_namespace_v1.go
+++ b/kubernetes/data_source_kubernetes_namespace_v1.go
@@ -10,6 +10,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 	corev1 "k8s.io/api/core/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -51,6 +52,9 @@ func dataSourceKubernetesNamespaceV1Read(ctx context.Context, d *schema.Resource
 
 	namespace, err := conn.CoreV1().Namespaces().Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_nodes.go b/kubernetes/data_source_kubernetes_nodes.go
index 9231f95a..172475f9 100644
--- a/kubernetes/data_source_kubernetes_nodes.go
+++ b/kubernetes/data_source_kubernetes_nodes.go
@@ -12,6 +12,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
 )
@@ -89,6 +90,9 @@ func dataSourceKubernetesNodesRead(ctx context.Context, d *schema.ResourceData,
 	log.Printf("[INFO] Listing nodes")
 	nodesRaw, err := conn.CoreV1().Nodes().List(ctx, listOptions)
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		return diag.FromErr(err)
 	}
 	nodes := make([]interface{}, len(nodesRaw.Items))
diff --git a/kubernetes/data_source_kubernetes_persistent_volume_claim_v1.go b/kubernetes/data_source_kubernetes_persistent_volume_claim_v1.go
index 92771fd5..bfb717b4 100644
--- a/kubernetes/data_source_kubernetes_persistent_volume_claim_v1.go
+++ b/kubernetes/data_source_kubernetes_persistent_volume_claim_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -105,6 +106,9 @@ func dataSourceKubernetesPersistentVolumeClaimV1Read(ctx context.Context, d *sch
 	log.Printf("[INFO] Reading persistent volume claim %s", metadata.Name)
 	claim, err := conn.CoreV1().PersistentVolumeClaims(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_pod_v1.go b/kubernetes/data_source_kubernetes_pod_v1.go
index c944d0aa..ca2eeb3d 100644
--- a/kubernetes/data_source_kubernetes_pod_v1.go
+++ b/kubernetes/data_source_kubernetes_pod_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -55,6 +56,9 @@ func dataSourceKubernetesPodV1Read(ctx context.Context, d *schema.ResourceData,
 	log.Printf("[INFO] Reading pod %s", metadata.Name)
 	pod, err := conn.CoreV1().Pods(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_secret_v1.go b/kubernetes/data_source_kubernetes_secret_v1.go
index 49e6261e..1eed4cce 100644
--- a/kubernetes/data_source_kubernetes_secret_v1.go
+++ b/kubernetes/data_source_kubernetes_secret_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -61,6 +62,9 @@ func dataSourceKubernetesSecretV1Read(ctx context.Context, d *schema.ResourceDat
 	log.Printf("[INFO] Reading secret %s", metadata.Name)
 	secret, err := conn.CoreV1().Secrets(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		return diag.FromErr(err)
 	}
 	log.Printf("[INFO] Received secret: %#v", secret.ObjectMeta)
diff --git a/kubernetes/data_source_kubernetes_service_account_v1.go b/kubernetes/data_source_kubernetes_service_account_v1.go
index 8dadbb2f..5e29e2ac 100644
--- a/kubernetes/data_source_kubernetes_service_account_v1.go
+++ b/kubernetes/data_source_kubernetes_service_account_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -69,6 +70,10 @@ func dataSourceKubernetesServiceAccountV1Read(ctx context.Context, d *schema.Res
 	metadata := expandMetadata(d.Get("metadata").([]interface{}))
 	sa, err := conn.CoreV1().ServiceAccounts(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			d.SetId(buildId(sa.ObjectMeta))
+			return nil
+		}
 		return diag.Errorf("Unable to fetch service account from Kubernetes: %s", err)
 	}
 
@@ -84,6 +89,9 @@ func dataSourceKubernetesServiceAccountV1Read(ctx context.Context, d *schema.Res
 	log.Printf("[INFO] Reading service account %s", metadata.Name)
 	svcAcc, err := conn.CoreV1().ServiceAccounts(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		diagMsg = append(diagMsg, diag.FromErr(err)...)
 		return diagMsg
diff --git a/kubernetes/data_source_kubernetes_service_v1.go b/kubernetes/data_source_kubernetes_service_v1.go
index 8999de84..df37a3df 100644
--- a/kubernetes/data_source_kubernetes_service_v1.go
+++ b/kubernetes/data_source_kubernetes_service_v1.go
@@ -11,6 +11,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
 	corev1 "k8s.io/api/core/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -257,6 +258,9 @@ func dataSourceKubernetesServiceV1Read(ctx context.Context, d *schema.ResourceDa
 	log.Printf("[INFO] Reading service %s", metadata.Name)
 	svc, err := conn.CoreV1().Services(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}
diff --git a/kubernetes/data_source_kubernetes_storage_class_v1.go b/kubernetes/data_source_kubernetes_storage_class_v1.go
index 19d1bcf6..e23d065c 100644
--- a/kubernetes/data_source_kubernetes_storage_class_v1.go
+++ b/kubernetes/data_source_kubernetes_storage_class_v1.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -100,6 +101,9 @@ func dataSourceKubernetesStorageClassV1Read(ctx context.Context, d *schema.Resou
 	log.Printf("[INFO] Reading storage class %s", metadata.Name)
 	storageClass, err := conn.StorageV1().StorageClasses().Get(ctx, metadata.Name, metav1.GetOptions{})
 	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil
+		}
 		log.Printf("[DEBUG] Received error: %#v", err)
 		return diag.FromErr(err)
 	}



Test patch:
diff --git a/kubernetes/data_source_kubernetes_config_map_v1_test.go b/kubernetes/data_source_kubernetes_config_map_v1_test.go
index 8e74e979..4edd022c 100644
--- a/kubernetes/data_source_kubernetes_config_map_v1_test.go
+++ b/kubernetes/data_source_kubernetes_config_map_v1_test.go
@@ -47,6 +47,25 @@ func TestAccKubernetesDataSourceConfigMapV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceConfigMapV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_config_map_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-config-map-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{ // Use the data source to read the existing resource.
+				Config: testAccKubernetesDataSourceConfigMapV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "data.%", "0"),
+				),
+			},
+		},
+	})
+}
+
 // testAccKubernetesDataSourceConfigMapConfig_basic provides the terraform config
 // used to test basic functionality of the config_map data source.
 func testAccKubernetesDataSourceConfigMapV1_basic(name string) string {
@@ -82,3 +101,12 @@ func testAccKubernetesDataSourceConfigMapV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceConfigMapV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_config_map_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_endpoints_v1_test.go b/kubernetes/data_source_kubernetes_endpoints_v1_test.go
index a5139f98..bc11cfed 100644
--- a/kubernetes/data_source_kubernetes_endpoints_v1_test.go
+++ b/kubernetes/data_source_kubernetes_endpoints_v1_test.go
@@ -60,6 +60,26 @@ func TestAccKubernetesDataSourceEndpointsV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceEndpointsV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_endpoints_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-endpoint-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		CheckDestroy:      testAccCheckKubernetesEndpointV1Destroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceEndpointsV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "subset.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceEndpointsV1_read() string {
 	return `data "kubernetes_endpoints_v1" "test" {
   metadata {
@@ -68,3 +88,12 @@ func testAccKubernetesDataSourceEndpointsV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceEndpointsV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_endpoints_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_ingress_test.go b/kubernetes/data_source_kubernetes_ingress_test.go
index e859da34..3897e7b4 100644
--- a/kubernetes/data_source_kubernetes_ingress_test.go
+++ b/kubernetes/data_source_kubernetes_ingress_test.go
@@ -68,6 +68,28 @@ func TestAccKubernetesDataSourceIngress_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceIngress_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_ingress.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-ingress-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck: func() {
+			testAccPreCheck(t)
+			skipIfClusterVersionGreaterThanOrEqual(t, "1.22.0")
+		},
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceIngress_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "spec.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceIngress_basic(name string) string {
 	return fmt.Sprintf(`resource "kubernetes_ingress" "test" {
   metadata {
@@ -104,3 +126,12 @@ func testAccKubernetesDataSourceIngress_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceIngress_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_ingress" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_ingress_v1_test.go b/kubernetes/data_source_kubernetes_ingress_v1_test.go
index 8f542d19..495f90df 100644
--- a/kubernetes/data_source_kubernetes_ingress_v1_test.go
+++ b/kubernetes/data_source_kubernetes_ingress_v1_test.go
@@ -70,6 +70,28 @@ func TestAccKubernetesDataSourceIngressV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceIngressV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_ingress_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-ingress-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck: func() {
+			testAccPreCheck(t)
+			skipIfClusterVersionLessThan(t, "1.22.0")
+		},
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceIngressV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "spec.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceIngressV1_basic(name string) string {
 	return fmt.Sprintf(`resource "kubernetes_ingress_v1" "test" {
   metadata {
@@ -115,3 +137,12 @@ func testAccKubernetesDataSourceIngressV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceIngressV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_ingress_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1_test.go b/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1_test.go
index 6b3c4c76..e85f6a9b 100644
--- a/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1_test.go
+++ b/kubernetes/data_source_kubernetes_mutating_webhook_configuration_v1_test.go
@@ -101,6 +101,26 @@ func TestAccKubernetesDataSourceMutatingWebhookConfigurationV1_basic(t *testing.
 	})
 }
 
+func TestAccKubernetesDataSourceMutatingWebhookConfigurationV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_mutating_webhook_configuration_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-webhook-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck: func() {
+			testAccPreCheck(t)
+		},
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceMutatingWebhookConfigurationV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "webhook.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceMutatingWebhookConfigurationV1_basic(name string) string {
 	return fmt.Sprintf(`resource "kubernetes_mutating_webhook_configuration_v1" "test" {
   metadata {
@@ -141,3 +161,12 @@ func testAccKubernetesDataSourceMutatingWebhookConfigurationV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceMutatingWebhookConfigurationV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_mutating_webhook_configuration_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_namespace_v1_test.go b/kubernetes/data_source_kubernetes_namespace_v1_test.go
index bf259514..8da98962 100644
--- a/kubernetes/data_source_kubernetes_namespace_v1_test.go
+++ b/kubernetes/data_source_kubernetes_namespace_v1_test.go
@@ -4,8 +4,10 @@
 package kubernetes
 
 import (
+	"fmt"
 	"testing"
 
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
 )
 
@@ -31,6 +33,24 @@ func TestAccKubernetesDataSourceNamespaceV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceNamespaceV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_namespace_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-namespace-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceNamespaceV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "spec.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceNamespaceV1_basic() string {
 	return `data "kubernetes_namespace_v1" "test" {
   metadata {
@@ -39,3 +59,12 @@ func testAccKubernetesDataSourceNamespaceV1_basic() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceNamespaceV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_namespace_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_nodes_test.go b/kubernetes/data_source_kubernetes_nodes_test.go
index 36b5832a..d733fa11 100644
--- a/kubernetes/data_source_kubernetes_nodes_test.go
+++ b/kubernetes/data_source_kubernetes_nodes_test.go
@@ -50,6 +50,23 @@ func TestAccKubernetesDataSourceNodes_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceNodes_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_nodes.test"
+	checkFuncs := resource.ComposeAggregateTestCheckFunc(
+		resource.TestCheckResourceAttr(dataSourceName, "nodes.#", "0"),
+	)
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceNodes_nonexistent(),
+				Check:  checkFuncs,
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceNodes_basic() string {
 	return `data "kubernetes_nodes" "test" {}
 `
@@ -65,3 +82,14 @@ func testAccKubernetesDataSourceNodes_labels() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceNodes_nonexistent() string {
+	return `data "kubernetes_nodes" "test" {
+  metadata {
+    labels = {
+      "ceci-n.est-pas" = "une-node"
+    }
+  }
+}
+`
+}
diff --git a/kubernetes/data_source_kubernetes_persistent_volume_claim_v1_test.go b/kubernetes/data_source_kubernetes_persistent_volume_claim_v1_test.go
index 325bd757..33019a68 100644
--- a/kubernetes/data_source_kubernetes_persistent_volume_claim_v1_test.go
+++ b/kubernetes/data_source_kubernetes_persistent_volume_claim_v1_test.go
@@ -56,6 +56,25 @@ func TestAccKubernetesDataSourcePersistentVolumeClaimV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourcePersistentVolumeClaimV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_persistent_volume_claim_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-pvc-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{ // The first apply creates the resource. The second apply reads the resource using the data source.
+				Config: testAccKubernetesDataSourcePersistentVolumeClaimV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "spec.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourcePersistentVolumeClaimV1_basic(name string) string {
 	return fmt.Sprintf(`resource "kubernetes_persistent_volume_claim_v1" "test" {
   metadata {
@@ -98,3 +117,12 @@ func testAccKubernetesDataSourcePersistentVolumeClaimV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourcePersistentVolumeClaimV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_persistent_volume_claim_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_pod_v1_test.go b/kubernetes/data_source_kubernetes_pod_v1_test.go
index e8230131..b01d428f 100644
--- a/kubernetes/data_source_kubernetes_pod_v1_test.go
+++ b/kubernetes/data_source_kubernetes_pod_v1_test.go
@@ -40,6 +40,25 @@ func TestAccKubernetesDataSourcePodV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourcePodV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_pod_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-pod-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourcePodV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "spec.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourcePodV1_basic(name, imageName string) string {
 	return fmt.Sprintf(`resource "kubernetes_pod_v1" "test" {
   metadata {
@@ -63,3 +82,12 @@ func testAccKubernetesDataSourcePodV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourcePodV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_pod_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_secret_v1_test.go b/kubernetes/data_source_kubernetes_secret_v1_test.go
index 2a2ba84c..05b585dd 100644
--- a/kubernetes/data_source_kubernetes_secret_v1_test.go
+++ b/kubernetes/data_source_kubernetes_secret_v1_test.go
@@ -81,6 +81,25 @@ func TestAccKubernetesDataSourceSecretV1_generateName(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceSecretV1_not_found(t *testing.T) {
+	name := fmt.Sprintf("ceci-n.est-pas-une-secret-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+	datasourceName := "data.kubernetes_secret_v1.test"
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceSecretV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(datasourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(datasourceName, "data.%", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceSecretV1_generateName(generate_name string) string {
 	return fmt.Sprintf(`resource "kubernetes_secret_v1" "test" {
   metadata {
@@ -147,3 +166,12 @@ func testAccKubernetesDataSourceSecretV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceSecretV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_secret_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_service_account_v1_test.go b/kubernetes/data_source_kubernetes_service_account_v1_test.go
index ebdb5cfc..fd80fde5 100644
--- a/kubernetes/data_source_kubernetes_service_account_v1_test.go
+++ b/kubernetes/data_source_kubernetes_service_account_v1_test.go
@@ -80,6 +80,26 @@ func TestAccKubernetesDataSourceServiceAccountV1_default_secret(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceServiceAccountV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_service_account_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-service-account-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceServiceAccountV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "secret.#", "0"),
+					resource.TestCheckResourceAttr(dataSourceName, "image_pull_secret.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceServiceAccountV1_basic(name string) string {
 	return fmt.Sprintf(`resource "kubernetes_service_account_v1" "test" {
   metadata {
@@ -162,3 +182,12 @@ func testAccKubernetesDataSourceServiceAccountV1_default_secret_read(name string
 }
 `, name)
 }
+
+func testAccKubernetesDataSourceServiceAccountV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_service_account_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_service_v1_test.go b/kubernetes/data_source_kubernetes_service_v1_test.go
index 4e9f24a3..31bd1bf5 100644
--- a/kubernetes/data_source_kubernetes_service_v1_test.go
+++ b/kubernetes/data_source_kubernetes_service_v1_test.go
@@ -83,6 +83,26 @@ func TestAccKubernetesDataSourceServiceV1_basic(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceServiceV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_service_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-service-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesConfig_ignoreAnnotations() +
+					testAccKubernetesDataSourceServiceV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "spec.#", "0"),
+				),
+			},
+		},
+	})
+}
+
 func testAccKubernetesDataSourceServiceV1_basic(name string) string {
 	return fmt.Sprintf(`resource "kubernetes_service_v1" "test" {
   metadata {
@@ -118,3 +138,12 @@ func testAccKubernetesDataSourceServiceV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceServiceV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_service_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}
diff --git a/kubernetes/data_source_kubernetes_storage_class_v1_test.go b/kubernetes/data_source_kubernetes_storage_class_v1_test.go
index 633b32fc..c1a6f89b 100644
--- a/kubernetes/data_source_kubernetes_storage_class_v1_test.go
+++ b/kubernetes/data_source_kubernetes_storage_class_v1_test.go
@@ -73,6 +73,26 @@ func TestAccKubernetesDataSourceStorageClassV1_minikube(t *testing.T) {
 	})
 }
 
+func TestAccKubernetesDataSourceStorageClassV1_not_found(t *testing.T) {
+	dataSourceName := "data.kubernetes_storage_class_v1.test"
+	name := fmt.Sprintf("ceci-n.est-pas-une-storage-class-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { testAccPreCheck(t); skipIfNotRunningInKind(t) },
+		ProviderFactories: testAccProviderFactories,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKubernetesDataSourceStorageClassV1_nonexistent(name),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
+					resource.TestCheckResourceAttr(dataSourceName, "mount_options.#", "0"),
+					resource.TestCheckResourceAttr(dataSourceName, "parameters.%", "0"),
+				),
+			},
+		},
+	})
+}
+
 func TestAccKubernetesDataSourceStorageClassV1_gke(t *testing.T) {
 	resourceName := "kubernetes_storage_class_v1.test"
 	dataSourceName := "data.kubernetes_storage_class_v1.test"
@@ -178,3 +198,12 @@ func testAccKubernetesDataSourceStorageClassV1_read() string {
 }
 `
 }
+
+func testAccKubernetesDataSourceStorageClassV1_nonexistent(name string) string {
+	return fmt.Sprintf(`data "kubernetes_storage_class_v1" "test" {
+  metadata {
+    name = "%s"
+  }
+}
+`, name)
+}